﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-JAVA~~~i love you</title><link>http://www.blogjava.net/ayato/</link><description /><language>zh-cn</language><lastBuildDate>Sat, 18 Apr 2026 11:16:58 GMT</lastBuildDate><pubDate>Sat, 18 Apr 2026 11:16:58 GMT</pubDate><ttl>60</ttl><item><title>面向对象设计之LSP</title><link>http://www.blogjava.net/ayato/archive/2006/08/03/61427.html</link><dc:creator>it民工</dc:creator><author>it民工</author><pubDate>Wed, 02 Aug 2006 16:28:00 GMT</pubDate><guid>http://www.blogjava.net/ayato/archive/2006/08/03/61427.html</guid><wfw:comment>http://www.blogjava.net/ayato/comments/61427.html</wfw:comment><comments>http://www.blogjava.net/ayato/archive/2006/08/03/61427.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/ayato/comments/commentRss/61427.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ayato/services/trackbacks/61427.html</trackback:ping><description><![CDATA[
		<p>      前段时间完成我的毕业论文，是关于面向对象设计原则和设计模式的一些讨论，为此重读了Robert C.Martin的《Aglile Software Development Principles，Patterns and Pratices》这本著作，对面向对象设计有了一个新的认识，在这里和大家分享一下。<br />      《Agile》一书中提到一系列的面向对象设计原则，其中一条是叫作LSP---Liskov替换原则。LSP是Barbara Liskov在她1988年的论文中提出的，其内容是：子类必须能够完全替换掉它的父类。LSP是使OCP成立的条件之一（关于OCP在以后的文章会作讨论），二者都是面向对象的多态和抽象的基础。<br />      举个例子，当我们有一个Car这个类</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Car {<br />    <br />    </span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> run(){<br />        System.out.println(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">I am running</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">);<br />    }<br />    <br />    </span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> stop(){<br />        System.out.println(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">I am stop</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">);<br />    }<br />}</span>
		</div>
		<br />现在，如果有一个类与Car类有关系，在面向对象中，类之间的关系就是组合和继承。当确定这个类为另外一个类的使用者、拥有者时就用组合，譬如Person类使用Car类。使用者的类有一个特征就是运行时多态放在它们之间是不管用的，譬如Person可能有一些eat、laugh等公共方法，如果Person是Car的子类，根据运行时多态就可以用Car来替换Person，Car就有得eat这个方法，显然是不合逻辑的。<br />    如果确定是有一种特殊的Car会飞的，除了run和stop之外还有一个fly的方法，现在就是使用继承的场合。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> FlyingCar </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> Car {<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> fly(){<br />        System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">I am Fly</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />    }<br />}</span></div><br />虽然使用了继承，但是确违反了LSP。因为Car中并没有fly这个方法，运行时多态便被破坏。为了获得多态性，将Car重构为抽象类，在其中添加一个抽象的fly方法，多态性便得以保存。但是这样做的话就说明所有Car的抽象都是会fly的，这显然是不合理。为此，应该去掉Car中的fly方法，Car就不是抽象类，再由Car这个抽象类派生出抽象的FlyingCar，里面包含fly的抽象方法。这样，FlyingCar抽象类和它的派生类就确保遵守了LSP了。<br />      还有一种做法，将fly方法抽象到一个Flyable接口中。FlyingCar在继承Car的同时实现Flyable接口，就是说，FlyingCar的上级父类就是Car和Flyable，按照LSP是完全可以覆盖父类的。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> Flyable {<br /><br />    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> fly();<br />}</span></div><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> FlyingCar </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> Car </span><span style="COLOR: #0000ff">implements</span><span style="COLOR: #000000"> Flyable {<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> fly(){<br />        System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">I am fly</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />    }<br />}</span></div><br />使用运行时多态时要获得fly方法必须转型为Flyable接口<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> CarMain {<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> main(String[] args) {<br />        Car car</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> FlyingCar();<br />        car.run();<br />        car.stop();<br />        ((Flyable)car).fly();<br />    }<br />}</span></div><br />LSP是指导使用继承的准则。继承肯定是子类添加父类所不具有的新方法的，此时若忽略LSP，多态性便会在设计中消失。所以当使用继承时，为了保证多态性，就需要遵守LSP多做一些工作了。<img src ="http://www.blogjava.net/ayato/aggbug/61427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ayato/" target="_blank">it民工</a> 2006-08-03 00:28 <a href="http://www.blogjava.net/ayato/archive/2006/08/03/61427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Common IO学习</title><link>http://www.blogjava.net/ayato/archive/2006/08/02/61407.html</link><dc:creator>it民工</dc:creator><author>it民工</author><pubDate>Wed, 02 Aug 2006 14:11:00 GMT</pubDate><guid>http://www.blogjava.net/ayato/archive/2006/08/02/61407.html</guid><wfw:comment>http://www.blogjava.net/ayato/comments/61407.html</wfw:comment><comments>http://www.blogjava.net/ayato/archive/2006/08/02/61407.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ayato/comments/commentRss/61407.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ayato/services/trackbacks/61407.html</trackback:ping><description><![CDATA[         一直都在看BlogJava上的文章，从众多的Java爱好者那里学到了不少的知识，但是却没有在自己blog上发过文章。渐渐地，觉得这种只会索取不作贡献的行为是不行的，请原谅我有点害羞吧，哈哈。所以从现在开始我会陆续地在blog上面发表关于Java、软件开发的文章，希望大家能多多指教。<br />         闲话说到这，近来在阅读一本关于Jakarta Common的书，就写一下关于Jakarta Common这一系列工具的文章吧。什么是Jakarta Common呢？它是一系列Apache的子项目，包括Collections、XML、JavaBean、IO等一系列增强Java的工具类，在许多Apache的项目中都可以看到它们的身影，如Struts。现在介绍的是Common IO，这个包主要使IO与网络之间编程更加方便，编码更加清晰。<br />         其中CopyUtils和IOUtils提供一系列静态方法使到stream和Reader/Writer和String之间的转变更加容易希望从一个InputStream将读取的流转变为FileWriter写入一个文件，只需要使用CopyUtils的copy方法，这个方法有多个重载版本，这里接受一个InputStream的对象和一个FileWriter的对象。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> performCopying(){<br />        Writer writer</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br />        InputStream inputStream</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br />        </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> {<br />            writer</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> FileWriter(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">test.dat</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />            inputStream</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">getClass().getResourceAsStream(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">./test.resource</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />            CopyUtils.copy(inputStream,writer);<br />        } </span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (IOException e) {<br />            e.printStackTrace();<br />        }</span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000">{<br />            IOUtils.closeQuietly(writer);<br />            IOUtils.closeQuietly(inputStream);<br />        }<br />    }</span></div><br />最后很方便的是，使用IOUtils的closeQuietly静态方法就可以方便地关闭资源。同样地，从一个网络上的地址上获得网页内容到字符串也是非常地直观。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> urlToString(){<br />        URL url</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br />        InputStream inputStream</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br />        <br />        </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> {<br />            url</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> URL(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">http://www.21cn.com</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />            inputStream</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">url.openStream();<br />            String contents</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">IOUtils.toString(inputStream);<br />            System.out.println(contents);<br />        } </span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (MalformedURLException e) {<br />            e.printStackTrace();<br />        } </span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (IOException e) {<br />            e.printStackTrace();<br />        }<br />    }</span></div><br />使用IOUtils的toString的一个重载版本就可以方便地做到上述功能。Common IO还有许多有用的功能，在以后的文章会继续探讨。<img src ="http://www.blogjava.net/ayato/aggbug/61407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ayato/" target="_blank">it民工</a> 2006-08-02 22:11 <a href="http://www.blogjava.net/ayato/archive/2006/08/02/61407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>