從制造到創造
          軟件工程師成長之路
          posts - 292,  comments - 96,  trackbacks - 0

          8.1 接口的概念和基本特征

          (1)、接口中的成員變量默認都是public、static、final類型的,必須被顯式初始化;
          (2)、接口中的方法默認都是public、abstract類型的;
          (3)、接口中只能包含public、static、final類型的成員變量和public、abstract類型的成員方法;
          (4)、接口沒有構造方法,不能被實例化;
          (5)、一個接口不能實現另一個接口,但可以繼承多個其他接口;
          (6)、接口必須通過類來實現它的抽象方法。類實現接口的關鍵字是implements;
          (7)、與子類繼承抽象父類相似,當類實現了某個接口時,它必須實現接口中所有的抽象方法,否則這個類必須被定義為抽象類;
          (8)、不允許創建接口類型的實例,但允許定義接口類型的引用變量,該變量引用實現了這個接口的類的實例;
          (9)、一個類只能繼承一個直接的父類,但能實現多個接口。

          8.2 比較抽象類與接口

          相同點:
          • 代表系統的抽象層
          • 都不能被實例化
          • 都能包含抽象方法
          兩大區別:
          • 在抽象類中可以為部分方法提供默認的實現,從而避免在子類中重復實現它們,提高代碼的可重用性,這是抽象類的優勢所在;而接口中只能包含抽象方法;
          • 一個類只能繼承一個直接的父類,這個父類有可能是抽象類;但一個類可以實現多個接口,這是接口的優勢所在。 
          使用接口和抽象類的原則:
          1. 用接口作為系統與外界交互的窗口;
          2. 由于外界使用者依賴系統的接口,并且系統內部會實現接口,因此接口本身必須十分穩定,接口一旦制訂,就不允許隨意修改,否則會對外界使用者及系統內部都造成影響。
          3. 用抽象類來定制系統中的擴展點。 

          8.3 與接口相關的設計模式

          8.3.1 定制服務模式
          如何設計接口?定制服務模式提出了設計精粒度的接口的原則。
          8.3.2 適配器模式

          當兩個系統之間接口不匹配時,如果處理?適配器模式提供了接口轉換方案。

          包括繼承實現方式和組合實現方式。優先考慮用組合關系來實現適配器。

          8.3.3 默認適配器模式
          為了簡化編程,JDK為MouseListener提供了一個默認適配器MouseAdapter,它實現了MouseListener接口,為所有的方法提供了空的方法體。用戶自定義的MyMouseLIstener監聽器可以繼承MouseAdapter類,在MyMouseListener類中,只需要覆蓋特定的方法,而不必實現所有的方法。使用默認適配器可以簡化編程,但缺點是該類不能在繼承其他的類。
          8.3.4 代理模式

          下面以房屋出租人的代理為例,介紹代理模式的運用。在下圖中,出租人Renter和代理Deputy都具有RenterIFC接口。Tenant類代表租賃人,HouseMarket類代表整個房產市場,它記錄了所有房產代理人的信息,出租人從房產市場找到房產代理人。



          為了簡化起見,假定一個代理人只會為一個出租人做代理,租賃人租房屋rentHouse()的大致過程如下:

          1. 從房產市場上找到一個房產代理人,即調用HouseMarket對象的findRenter()方法;
          2. 報出期望的租金價格,征求代理人的意見,即調用Deputy對象的isAgree()方法;
          3. 代理人的處理方式為:如果租賃人的報價低于出租人的租金價格底線,就立即做出拒絕答復;否則征求出租人的意見,即調用Renter對象的isAgree()方法。
          4. 出租人的處理方式為:如果租賃人的報價比租金價格底線多100元,就同意出租
          5. 如果租賃人得到代理人同意的答復,就從存款中取出租金,通知代理人領取租金,即調用Deputy對象的fetchRent()方法
          6. 代理人通知出租人領取租金,即調用Renter對象的fecthRent()方法。 


           房屋租賃交易順利執行的時序圖

          源代碼:

          /**
           * RetnerIFC 接口,它定義了出租人的兩個行為,即決定是否同意按租賃人提出的價格出租房屋,以及收房租
           * 
           * 
          @author XL
           * 
           
          */
          public interface RenterIFC {
              
          /**
               * 是否同意按租賃人提出的價格出租房屋
               * 
               * 
          @param expectedRent
               * 
          @return
               
          */
              
          public boolean isAgree(double expectedRent);

              
          /**
               * 收房租
               * 
               * 
          @param rent
               
          */
              
          public void fetchRent(double rent);
          }


          /**
           * 房屋出租人
           * 
           * 
          @author XL
           * 
           
          */
          public class Renter implements RenterIFC {

              
          /**
               * 房屋租金最低價格
               
          */
              
          private double rentDeadLine;

              
          /**
               * 存款
               
          */
              
          private double money;

              
          /**
               * 
          @param rentDeadLine
               * 
          @param money
               
          */
              
          public Renter(double rentDeadLine, double money) {
                  
          super();
                  System.out.println(
          "New Renter, rentDeadLine: " + rentDeadLine
                          
          + ", saveMoney: " + money);
                  
          this.rentDeadLine = rentDeadLine;
                  
          this.money = money;
              }

              
          /*
               * (non-Javadoc)
               * 
               * @see chapter08.d0800.RenterIFC#fetchRent(double)
               
          */
              
          public void fetchRent(double rent) {
                  System.out.println(
          "OK, you can use the house.");
                  money 
          += rent;
              }

              
          /*
               * (non-Javadoc) 如果租賃人的期望價格比房屋租金最低價格多100元,則同意出租
               * 
               * @see chapter08.d0800.RenterIFC#isAgree(double)
               
          */
              
          public boolean isAgree(double expectedRent) {
                  System.out.println(
          "If the money less 100 than the rentDeadLine.");
                  
          return expectedRent - this.rentDeadLine > 100;
              }

              
          /**
               * 
          @return
               
          */
              
          public double getRentDeadLine() {
                  
          return rentDeadLine;
              }
          }


          /**
           * 房產代理人
           * 
           * 
          @author XL
           * 
           
          */
          public class Deputy implements RenterIFC {

              
          private Renter renter;

              
          /**
               * 接受代理
               * 
               * 
          @param renter
               
          */
              
          public void registerRenter(Renter renter) {
                  System.out.println(
          "OK, I have some business.");
                  
          this.renter = renter;
              }

              
          public void fetchRent(double rent) {
                  System.out.println(
          "Get the monty: " + rent);
                  renter.fetchRent(rent);
              }

              
          /*
               * (non-Javadoc) 如果租賃人的期望價格低于房屋租金最低價格,則不同意出租 否則請示出租人的意見
               * 
               * @see chapter08.d0800.RenterIFC#isAgree(double)
               
          */
              
          public boolean isAgree(double expectedRent) {
                  
          //
                  if (expectedRent < renter.getRentDeadLine()) {
                      System.out.println(
          "Sorry, you can't rent the house.");
                      
          return false;
                  } 
          else {
                      System.out.println(
          "Let me ask the renter.");
                      
          return renter.isAgree(expectedRent);
                  }
              }

          }

           

          import java.util.HashSet;
          import java.util.Set;

          /**
           * 
          @author XL
           * 
           
          */
          public class HouseMarket {
              
          private static Set<RenterIFC> renters = new HashSet<RenterIFC>();

              
          public static void registerRenter(RenterIFC deputy) {
                  System.out.println(
          "A new man has registered!");
                  renters.add(deputy);
              }

              
          public static RenterIFC findRenter() {
                  System.out.println(
          "Let's find something!");
                  
          return (RenterIFC) renters.iterator().next();
              }
          }

           

          /**
           * 房屋租賃人
           * 
           * 
          @author XL
           * 
           
          */
          public class Tenant {
              
          private double money;

              
          public Tenant(double money) {
                  
          // 
                  System.out.println("New Tenant!");
                  System.out.println(
          "I have " + money);
                  
          this.money = money;
              }

              
          public boolean rentHouse(double expectedRent) {
                  
          // 從房地產市場找到一個房產代理人
                  RenterIFC renter = HouseMarket.findRenter();
                  
                  System.out.println(
          "I can offer " + expectedRent);
                  
                  
          // 如果代理人不同意預期的租金價格,就拉倒,否則繼續執行
                  if (!renter.isAgree(expectedRent)) {
                      System.out.println(
          "I can't offer any more!");
                      
          return false;
                  }

                  
          // 從存款中取出預付租金
                  money -= expectedRent;
                  System.out.println(
          "OK, get the money, " + expectedRent);

                  
          // 把租金交給房產代理人
                  renter.fetchRent(expectedRent);

                  
          return true;
              }
          }

           

          /**
           * 
          @author XL
           *
           
          */
          public class AppMain {

              
          /**
               * 
          @param args
               
          */
              
          public static void main(String[] args) {
                  
          // 創建一個房屋出租人,房屋租金最低價格為2000元,存款1萬元
                  Renter renter = new Renter(200010000);
                  
                  
          // 創建一個房產代理人
                  Deputy deputy = new Deputy();
                  
                  
          // 房產代理人到房產市場登記
                  HouseMarket.registerRenter(deputy);
                  
                  
          // 建立房屋出租人和房產代理人的委托關系
                  deputy.registerRenter(renter);
                  
                  
                  
          // 創建一個房屋租賃人,存款為2萬元
                  Tenant tenant = new Tenant(20000);
                  
                  
          // 房屋租賃人試圖租賃期望租金為1800元的房屋,遭到房產代理人拒絕
                  tenant.rentHouse(1800);
                  
                  
          // 房屋租賃人試圖租賃期望租金為2300元的房屋,租房成功
                  tenant.rentHouse(2300);
              }

          }

          輸出結果:

          New Renter, rentDeadLine: 2000.0, saveMoney: 10000.0
          A new man has registered!
          OK, I have some business.
          New Tenant!
          I have 20000.0
          Let's find something!
          I can offer 1800.0
          Sorry, you can't rent the house.
          I can't offer any more!
          Let's find something!
          I can offer 2300.0
          Let me ask the renter.
          If the money less 100 than the rentDeadLine.
          OK, get the money, 2300.0
          Get the monty: 2300.0
          OK, you can use the house.


          8.3.5 標識類型模式

          標識類型接口沒有任何方法,僅代表一種抽象類型。
          在JDK中,有如下兩個典型的標識類型接口:

          • java.io.Serializable接口:實現該接口的類可以被序列化。
          • java.io.Remote接口:實現該接口的類的實例可以作為遠程對象。
          8.3.6 常量接口模式
          posted on 2008-02-19 18:03 CoderDream 閱讀(402) 評論(0)  編輯  收藏 所屬分類: 經驗點滴

          <2008年2月>
          272829303112
          3456789
          10111213141516
          17181920212223
          2425262728291
          2345678

          常用鏈接

          留言簿(9)

          我參與的團隊

          隨筆分類(245)

          隨筆檔案(239)

          文章分類(3)

          文章檔案(3)

          收藏夾(576)

          友情鏈接

          搜索

          •  

          積分與排名

          • 積分 - 458376
          • 排名 - 114

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 高安市| 河曲县| 海安县| 本溪市| 伊川县| 云阳县| 江川县| 崇州市| 青岛市| 克东县| 外汇| 河北省| 浪卡子县| 湾仔区| 英超| 嘉鱼县| 咸宁市| 新平| 资兴市| 定兴县| 盐边县| 台南市| 分宜县| 毕节市| 乌拉特前旗| 德江县| 长武县| 土默特左旗| 南城县| 阳信县| 贡嘎县| 伊吾县| 麻阳| 郓城县| 永丰县| 嵊州市| 九台市| 玛多县| 察隅县| 中山市| 永新县|