熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

選擇Java接口還是抽象類

2013-11-23 19:09:47  來源: Java核心技術 

   
  選擇Java接口還是抽象類
  
  作者俞良松 本文選自開放系統世界-賽迪網
  
  很多人有過這樣的疑問為什麼有的地方必須使用接口而不是抽象類而在另一些地方又必須使用抽象類而不是接口呢?或者說在考慮Java類的一般化問題時很多人會在接口和抽象類之間猶豫不決甚至隨便選擇一種
  
  實際上接口和抽象類的選擇不是隨心所欲的 要理解接口和抽象類的選擇原則有兩個概念很重要對象的行為和對象的實現如果一個實體可以有多種實現方式則在設計實體行為的描述方式時應當達到這樣一個目標在使用實體的時候無需詳細了解實體行為的實現方式也就是說要把對象的行為和對象的實現分離開來既然Java的接口和抽象類都可以定義不提供具體實現的方法在分離對象的行為和對象的實現時到底應該使用接口還是使用抽象類呢?
  
  通過抽象類建立行為模型
  
  在接口和抽象類的選擇上必須遵守這樣一個原則行為模型應該總是通過接口而不是抽象類定義為了說明其原因下面試著通過抽象類建立行為模型看看會出現什麼問題
  
  假設要為銷售部門設計一個軟件這個軟件包含一個發動機(Motor)實體顯然無法在發動機對象中詳細地描述發動機的方方面面只能描述某些對當前軟件來說重要的特征至於發動機的哪些特征是重要的則要與用戶(銷售部門)交流才能確定
  
  銷售部門的人要求每一個發動機都有一個稱為馬力的參數對於他們來說這是惟一值得關心的參數基於這一判斷可以把發動機的行為定義為以下行為
  
  行為查詢發動機的馬力發動機將返回一個表示馬力的整數
  
  雖然現在還不清楚發動機如何取得馬力這個參數但可以肯定發動機一定支持這個行為而且這是所有發動機惟一值得關注的行為特征這個行為特征既可以用接口定義也可以用抽象類定義為了說明用抽象類定義可能出現的問題下面用抽象類建立發動機的行為模型並用Java方法描述行為代碼如下
  
  
  
  public abstract Motor{
  
  abstract public int getHorsepower();
  
  }
  
  
  
  在Motor抽象類的基礎上構造出多種具體實現例如A型發動機B型發動機等再加上系統的其它部分最後得到版的軟件並交付使用一段時間過去了現在要設計版的軟件在評估版軟件需求的過程中發現一小部分發動機是電池驅動的而電池需要一定的充電時間銷售部門的人希望能夠通過計算機查閱充電時間根據這一要求定義一個新的行為如圖所示
  
  行為查詢電驅動發動機的充電時間發動機將返回一個表示充電時間的整數
  
  用Java方法來描述這個行為代碼如下
  
  
  
  public abstract BatteryPoweredMotor extends Motor{
  
  abstract public int getTimeToRecharge();
  
  }
  
  
  
  在銷售部門的軟件中電驅動發動機也以類的形式實現但這些類從BatteryPoweredMotor而不是Motor派生這些改動加入到版軟件之後銷售部門很滿意隨著業務的不斷發展不久之後光驅動的發動機出現了銷售部門要求光驅動發動機需要一定光能才能運轉光能以流明(Lumen)度量這個信息對客戶很重要因為下雨或多雲的天氣裡某些光驅動發動機可能無法運轉銷售部門要求為軟件增加對光驅動發動機的支持所以要定義一個新的行為
  
  行為查詢光驅動發動機能夠正常運轉所需要的最小流明數發動機返回一個整數
  
  再定義一個抽象類並把行為轉換成Java方法代碼如下
  
  
  
  public abstract SolarPoweredMotor extends Motor{
  
  abstract public int getLumensToOperate(); 
  選擇Java接口還是抽象類
  
  作者俞良松 本文選自開放系統世界-賽迪網
  
  很多人有過這樣的疑問為什麼有的地方必須使用接口而不是抽象類而在另一些地方又必須使用抽象類而不是接口呢?或者說在考慮Java類的一般化問題時很多人會在接口和抽象類之間猶豫不決甚至隨便選擇一種
  
  實際上接口和抽象類的選擇不是隨心所欲的 要理解接口和抽象類的選擇原則有兩個概念很重要對象的行為和對象的實現如果一個實體可以有多種實現方式則在設計實體行為的描述方式時應當達到這樣一個目標在使用實體的時候無需詳細了解實體行為的實現方式也就是說要把對象的行為和對象的實現分離開來既然Java的接口和抽象類都可以定義不提供具體實現的方法在分離對象的行為和對象的實現時到底應該使用接口還是使用抽象類呢?
  
  通過抽象類建立行為模型
  
  在接口和抽象類的選擇上必須遵守這樣一個原則行為模型應該總是通過接口而不是抽象類定義為了說明其原因下面試著通過抽象類建立行為模型看看會出現什麼問題
  
  假設要為銷售部門設計一個軟件這個軟件包含一個發動機(Motor)實體顯然無法在發動機對象中詳細地描述發動機的方方面面只能描述某些對當前軟件來說重要的特征至於發動機的哪些特征是重要的則要與用戶(銷售部門)交流才能確定
  
  銷售部門的人要求每一個發動機都有一個稱為馬力的參數對於他們來說這是惟一值得關心的參數基於這一判斷可以把發動機的行為定義為以下行為
  
  行為查詢發動機的馬力發動機將返回一個表示馬力的整數
  
  雖然現在還不清楚發動機如何取得馬力這個參數但可以肯定發動機一定支持這個行為而且這是所有發動機惟一值得關注的行為特征這個行為特征既可以用接口定義也可以用抽象類定義為了說明用抽象類定義可能出現的問題下面用抽象類建立發動機的行為模型並用Java方法描述行為代碼如下
  
  
  
  public abstract Motor{
  
  abstract public int getHorsepower();
  
  }
  
  
  
  在Motor抽象類的基礎上構造出多種具體實現例如A型發動機B型發動機等再加上系統的其它部分最後得到版的軟件並交付使用一段時間過去了現在要設計版的軟件在評估版軟件需求的過程中發現一小部分發動機是電池驅動的而電池需要一定的充電時間銷售部門的人希望能夠通過計算機查閱充電時間根據這一要求定義一個新的行為如圖所示
  
  行為查詢電驅動發動機的充電時間發動機將返回一個表示充電時間的整數
  
  用Java方法來描述這個行為代碼如下
  
  
  
  public abstract BatteryPoweredMotor extends Motor{
  
  abstract public int getTimeToRecharge();
  
  }
  
  
  
  在銷售部門的軟件中電驅動發動機也以類的形式實現但這些類從BatteryPoweredMotor而不是Motor派生這些改動加入到版軟件之後銷售部門很滿意隨著業務的不斷發展不久之後光驅動的發動機出現了銷售部門要求光驅動發動機需要一定光能才能運轉光能以流明(Lumen)度量這個信息對客戶很重要因為下雨或多雲的天氣裡某些光驅動發動機可能無法運轉銷售部門要求為軟件增加對光驅動發動機的支持所以要定義一個新的行為
  
  行為查詢光驅動發動機能夠正常運轉所需要的最小流明數發動機返回一個整數
  
  再定義一個抽象類並把行為轉換成Java方法代碼如下
  
  
  
  public abstract SolarPoweredMotor extends Motor{
  
  abstract public int getLumensToOperate();
  
  }
  
   
  
  如圖所示SolarPoweredMotor和BatteryPoweredMotor都從Motor抽象類派生在整個軟件中%以上的代碼以相同的方式對待所有的發動機偶爾需要檢查一下發動機是光驅動還是電驅動使用instanceof實現代碼如下
  
  [color=#]
  
  if (instanceof SolarPoweredMotor){}
  
  if (instanceof BatteryPoweredMotor){}
  
  
  
  無論是哪種發動機馬力這個參數都很重要所以在所有派生的抽象類(SolarPoweredMotor和BatteryPoweredMotor)中getHorsepower()方法都有效
  
  現在銷售部門又有了一種新的發動機它是一種既有電驅動又有光驅動的雙重驅動發動機光驅動和電驅動的行為本身沒有變化但新的發動機同時支持兩種行為在考慮如何定義新型的光電驅動發動機時接口和抽象類的差別開始顯示出來了新的目標是在增加新型發動機的前提下盡量少改動代碼因為與光驅動發動機電驅動發動機有關的代碼已經過全面的測試不存在已知的Bug為了增加光電驅動發動機要定義一個新的SolarBatteryPowered抽象類如果讓SolarBatteryPowered從Motor抽象類派生SolarBatteryPowered將不支持針對光驅動發動機和電驅動發動機的instanceof操作也就是說如果查詢一個光電驅動的發動機是光驅動的還是電驅動的得到的答案是都不是
  
  如果讓SolarBatteryPowered從SolarPoweredMotor(或BatteryPoweredMotor)抽象類派生類似的問題也會出現SolarBatteryPowered將不支持針
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26371.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.