JAVA~~~i love you

          2006年8月3日

          面向對象設計之LSP

          ??????前段時間完成我的畢業論文,是關于面向對象設計原則和設計模式的一些討論,為此重讀了Robert C.Martin的《Aglile Software Development Principles,Patterns and Pratices》這本著作,對面向對象設計有了一個新的認識,在這里和大家分享一下。
          ??????《Agile》一書中提到一系列的面向對象設計原則,其中一條是叫作LSP---Liskov替換原則。LSP是Barbara Liskov在她1988年的論文中提出的,其內容是:子類必須能夠完全替換掉它的父類。LSP是使OCP成立的條件之一(關于OCP在以后的文章會作討論),二者都是面向對象的多態和抽象的基礎。
          ??????舉個例子,當我們有一個Car這個類

          public ? class ?Car?{
          ????
          ????
          public ? void ?run(){
          ????????System.out.println(
          " I?am?running " );
          ????}
          ????
          ????
          public ? void ?stop(){
          ????????System.out.println(
          " I?am?stop " );
          ????}
          }

          現在,如果有一個類與Car類有關系,在面向對象中,類之間的關系就是組合和繼承。當確定這個類為另外一個類的使用者、擁有者時就用組合,譬如Person類使用Car類。使用者的類有一個特征就是運行時多態放在它們之間是不管用的,譬如Person可能有一些eat、laugh等公共方法,如果Person是Car的子類,根據運行時多態就可以用Car來替換Person,Car就有得eat這個方法,顯然是不合邏輯的。
          ??? 如果確定是有一種特殊的Car會飛的,除了run和stop之外還有一個fly的方法,現在就是使用繼承的場合。

          public?class?FlyingCar?extends?Car?{

          ????
          public?void?fly(){
          ????????System.out.println(
          "I?am?Fly");
          ????}
          }

          雖然使用了繼承,但是確違反了LSP。因為Car中并沒有fly這個方法,運行時多態便被破壞。為了獲得多態性,將Car重構為抽象類,在其中添加一個抽象的fly方法,多態性便得以保存。但是這樣做的話就說明所有Car的抽象都是會fly的,這顯然是不合理。為此,應該去掉Car中的fly方法,Car就不是抽象類,再由Car這個抽象類派生出抽象的FlyingCar,里面包含fly的抽象方法。這樣,FlyingCar抽象類和它的派生類就確保遵守了LSP了。
          ??????還有一種做法,將fly方法抽象到一個Flyable接口中。FlyingCar在繼承Car的同時實現Flyable接口,就是說,FlyingCar的上級父類就是Car和Flyable,按照LSP是完全可以覆蓋父類的。
          public?interface?Flyable?{

          ????
          void?fly();
          }

          public?class?FlyingCar?extends?Car?implements?Flyable?{

          ????
          public?void?fly(){
          ????????System.out.println(
          "I?am?fly");
          ????}
          }

          使用運行時多態時要獲得fly方法必須轉型為Flyable接口
          public?class?CarMain?{

          ????
          public?static?void?main(String[]?args)?{
          ????????Car?car
          =new?FlyingCar();
          ????????car.run();
          ????????car.stop();
          ????????((Flyable)car).fly();
          ????}
          }

          LSP是指導使用繼承的準則。繼承肯定是子類添加父類所不具有的新方法的,此時若忽略LSP,多態性便會在設計中消失。所以當使用繼承時,為了保證多態性,就需要遵守LSP多做一些工作了。

          posted @ 2006-08-03 00:28 it民工 閱讀(775) | 評論 (1)編輯 收藏

          2006年8月2日

          Common IO學習

          ?????????一直都在看BlogJava上的文章,從眾多的Java愛好者那里學到了不少的知識,但是卻沒有在自己blog上發過文章。漸漸地,覺得這種只會索取不作貢獻的行為是不行的,請原諒我有點害羞吧,哈哈。所以從現在開始我會陸續地在blog上面發表關于Java、軟件開發的文章,希望大家能多多指教。
          ?????????閑話說到這,近來在閱讀一本關于Jakarta Common的書,就寫一下關于Jakarta Common這一系列工具的文章吧。什么是Jakarta Common呢?它是一系列Apache的子項目,包括Collections、XML、JavaBean、IO等一系列增強Java的工具類,在許多Apache的項目中都可以看到它們的身影,如Struts。現在介紹的是Common IO,這個包主要使IO與網絡之間編程更加方便,編碼更加清晰。
          ?????????其中CopyUtils和IOUtils提供一系列靜態方法使到stream和Reader/Writer和String之間的轉變更加容易希望從一個InputStream將讀取的流轉變為FileWriter寫入一個文件,只需要使用CopyUtils的copy方法,這個方法有多個重載版本,這里接受一個InputStream的對象和一個FileWriter的對象。
          ????public?void?performCopying(){
          ????????Writer?writer
          =null;
          ????????InputStream?inputStream
          =null;
          ????????
          try?{
          ????????????writer
          =new?FileWriter("test.dat");
          ????????????inputStream
          =getClass().getResourceAsStream("./test.resource");
          ????????????CopyUtils.copy(inputStream,writer);
          ????????}?
          catch?(IOException?e)?{
          ????????????e.printStackTrace();
          ????????}
          finally{
          ????????????IOUtils.closeQuietly(writer);
          ????????????IOUtils.closeQuietly(inputStream);
          ????????}
          ????}

          最后很方便的是,使用IOUtils的closeQuietly靜態方法就可以方便地關閉資源。同樣地,從一個網絡上的地址上獲得網頁內容到字符串也是非常地直觀。
          ????public?void?urlToString(){
          ????????URL?url
          =null;
          ????????InputStream?inputStream
          =null;
          ????????
          ????????
          try?{
          ????????????url
          =new?URL("http://www.21cn.com");
          ????????????inputStream
          =url.openStream();
          ????????????String?contents
          =IOUtils.toString(inputStream);
          ????????????System.out.println(contents);
          ????????}?
          catch?(MalformedURLException?e)?{
          ????????????e.printStackTrace();
          ????????}?
          catch?(IOException?e)?{
          ????????????e.printStackTrace();
          ????????}
          ????}

          使用IOUtils的toString的一個重載版本就可以方便地做到上述功能。Common IO還有許多有用的功能,在以后的文章會繼續探討。

          posted @ 2006-08-02 22:11 it民工 閱讀(2001) | 評論 (0)編輯 收藏

          僅列出標題  
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 通许县| 石林| 广南县| 南乐县| 利辛县| 文成县| 阜康市| 青阳县| 嘉禾县| 体育| 曲周县| 攀枝花市| 平山县| 手游| 丽水市| 衢州市| 万源市| 上饶市| 永春县| 海盐县| 固安县| 边坝县| 武宣县| 建湖县| 永靖县| 宽甸| 延津县| 奈曼旗| 衡东县| 鄂伦春自治旗| 贡山| 舟山市| 腾冲县| 基隆市| 天台县| 万安县| 甘孜县| 长沙县| 萨嘎县| 武威市| 湟中县|