1. 程式人生 > >java 為什麼說多用組合,少用繼承?

java 為什麼說多用組合,少用繼承?

對類的功能的擴充套件,要多用組合,少用繼承組合:新的類由現有物件所組成。繼承:按照現有類的型別來建立新類,無需改變現有類的形式,採用現有類的形式並在其中新增新程式碼。

當繼承現有型別時,也就創造新的型別,這個新型別不僅包括現有型別的所有成員(儘管private成員被隱藏起來並且不可訪問,),更重要的是它複製了基類的介面,也就是說所有可以傳送給基類物件(父類)的訊息同時也可以傳送給匯出(子類)物件。由於通過傳送給類的訊息型別可知類的型別,所以這也就意味著匯出類與基類有相同的型別。


對於類的擴充套件,在面向物件的程式設計過程中,我們首先想到的是類的繼承,由子類繼承父類,從而完成了對子類功能的擴充套件。但是,面向物件的原則告訴我們,對類的功能的擴充套件要多用組合,而少用繼承。其中的原因有以下幾點:

第一、子類對父類的繼承是全部的公有和受保護的繼承,這使得子類可能繼承了對子類無用甚至有害的父類的方法。換句話說,子類只希望繼承父類的一部分方法,怎麼辦?
第二、實際的物件千變萬化,如果每一類的物件都有他們自己的類,儘管這些類都繼承了他們的父類,但有些時候還是會造成類的無限膨脹。
第三、 繼承的子類,實際上需要編譯期確定下來,這滿足不了需要在執行內才能確定物件的情況。而組合卻可以比繼承靈活得多,可以在執行期才決定某個物件。
嗨!光說這麼多一二三有什麼用,我們就是想看看實際情況是不是像上面說的那樣呢?還是來看看實際的例子吧!
現在我們需要這樣一個HashMap,它除了能按常規的Map那樣取值,如get(Object obj)。還能按位取值,像ArrayList那樣,按存入物件對的先後順序取值。

對於這樣一個問題,我們首先想到的是做一個類,它繼承了HashMap類,然後用一個ArrayList屬性來儲存存入的key,我們按key的位來取值,程式碼如下:
Java程式碼  收藏程式碼
  1. publicclass ListMap extends HashMap {  
  2. private List list;  
  3. public ListMap() {  
  4.          super();  
  5.           this.list = new ArrayList();  
  6. }  
  7. public Object put(Object key,Object value)  
  8. {  
  9.          if(list.contains(key))  
  10.           {  
  11.                  list.remove(key);  
  12.           }  
  13.          this.list.add(key);  
  14.           returnsuper.put(key,value);  
  15. }  
  16. public Object getKey(int i)  
  17. {  
  18.           returnthis.list.get(i);  
  19. }  
  20. public Object getValue(int i)  
  21. {  
  22.           returnthis.get(getKey(i));  
  23. }  
  24. publicint size()  
  25. {  
  26.           returnthis.list.size();  
  27. }  
  28. }  
  29. 這個ListMap類對HashMap作了一定的擴充套件,很簡單就實現了上面我們所要求的功能。然後我們對該類做一下測試:  
  30. ListMap map = new ListMap();  
  31.          map.put("a","111");  
  32.          map.put("v","190");  
  33.          map.put(

    相關推薦

    java 為什麼說多用組合繼承

    對類的功能的擴充套件,要多用組合,少用繼承。組合:新的類由現有物件所組成。繼承:按照現有類的型別來建立新類,無需改變現有類的形式,採用現有類的形式並在其中新增新程式碼。當繼承現有型別時,也就創造新的型別,這個新型別不僅包括現有型別的所有成員(儘管private成員被隱藏起來並

    CSS多個class樣式使用實踐-多用組合繼承

    先用繼承實現一個效果,程式碼如下:<style type="text/css">         .numberList1, .numberList2,  .numberList3, .numberList4{  border:1px solid #ccc;pa

    掛多個css還是新建class-多用組合繼承

    轉載於http://blog.csdn.net/hacke2/article/details/21707133 5. CSS的聚合/組合原則--掛多個class還是新建 CSS裡也包含了設計模式的6大原則,今天講講聚合/組合原則--多用組合,少用繼承 假設有如圖3-

    設計模式之多用組合繼承

    對類的功能的擴充套件,要多用組合,少用繼承。 對於類的擴充套件,在面向物件的程式設計過程中,我們首先想到的是類的繼承,由子類繼承父類,從而完成了對子類功能的擴充套件。但是,面向物件的原則告訴我們,對類的功能的擴充套件要多用組合,而少用繼承。其中的原因有以下幾點: 第一、子類

    組合還是繼承這是一個問題?——由模式談面向物件的原則之多用組合繼承

                                                          組合還是繼承,這是一個問題                                              ——由模式談面向物件的原則之多用組合、少用繼承剛剛接觸模式或者學習模式的人,經常

    設計模式之美學習(八):為何說要多用組合繼承?如何決定該組合還是繼承

    在面向物件程式設計中,有一條非常經典的設計原則,那就是:組合優於繼承,多用組合少用繼承。為什麼不推薦使用繼承?組合相比繼承有哪些優勢?如何判斷該用組合還是繼承? 為什麼不推薦使用繼承? 繼承是面向物件的四大特性之一,用來表示類之間的 is-a 關係,可以解決程式碼複用的問題。雖然繼承有諸多作用,但繼承層次過深

    為何說要多用組合繼承?如何決定該組合還是繼承

    在面向物件程式設計中,有一條非常經典的設計原則,那就是:組合優於繼承,多用組合少用繼承。為什麼不推薦使用繼承?組合相比繼承有哪些優勢?如何判斷該用組合還是繼承?今天,我們就圍繞著這三個問題,來詳細講解一下這條設計原則。 ## 為什麼不推薦使用繼承? 繼承是面向物件的四大特性之一,用來表示類之間的 is-a

    4、多用類型常量#define預處理指令

    報錯 作用域 生成 model 聲明 stat 指令 方法 類常量 摒棄: #define ANIMATION_DURATION 0.3 #define ERROR_MESSAGE @“ErrorMessage” 1)沒有常量的類型信息 2)假設此指令聲明在某個頭文件中

    3、多用字面量語法與之等價的方法

    keys obj ble alloc ive 3.1 per 無法 bsp 1、字面字符串 摒棄: NSString *someString = [[NSString alloc] initWithString: @"Effective Objective-C 2.0"];

    第41條:多用派發隊列同步鎖

    線程 ati 之前 lock col class logs pan 同步機制   本條要點:(作者總結)      在 Objective-C 中,如果有多個線程要執行同一份代碼,那麽有時可能會出問題。這種情況下,通常要使用鎖來實現某種同步機制。在 GCD 出現之前,有

    3.多用字面量語法與之等價的方法

    使用字面量語法(literal syntax)可以縮減原始碼長度,使其更易讀。 字面數值 有時需要把整數、浮點數、布林值封入 OC 物件中,這種情況下可以用 NSNumber 類,該類可以處理多種型別的數值。 // 不用字面量,建立一個數字 NSNumber *someN

    4.多用型別常量#define預處理命令

    #define ANIMATION_DURATION 0.3 缺點: 1)這樣定義沒有型別資訊,使閱讀程式碼的人難以理解其意圖。 2)假設此指令宣告在了某個標頭檔案中,那麼所有引入這個標頭檔案的程式碼,其ANIMATION_DURATION都會背替換為0.3。 更好的

    多用塊列舉for迴圈

    原文連結:http://www.jianshu.com/p/f76e8c62a755 著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。        注:本文來自《Effective Objective-C 2.0編寫高質量iOS 與 OS X程式碼的52個有

    寫高質量OC程式碼52建議總結:48.多用塊列舉for迴圈

    以下是for迴圈針對NSArray,NSSet,NSDictionary的遍歷。字典和set都是無序的,無法根據特定的整數下標直接訪問其值。遍歷set和dictionary都需要而外建立陣列儲存物件和key。這個中介陣列增加了不必要的而外開支。 -(void)demofor

    面向對象為什麽要多用對象模式而繼承模式?

    blog tis tps 總結 template 原來 css 方式 用戶 進來學習java的時候遇到了一些經驗說多用對象模式,少用繼承模式。如今寫一點感想。 面向對象的對象之間的哦

    java操作linux調shell命令

    api rsh pos orm exec creat shell cep time() import org.junit.jupiter.api.Test; import java.io.BufferedReader; import java.io.IOExce

    編寫一個Java應用程式戶在輸入對話方塊中輸入兩個日期後(日期格式為YYYYMMDD如1999年1月12日應輸入為19990112)程式將判斷兩個日期的先後順序以及兩個日期之間的間隔天數(例

    編寫一個Java應用程式,當用戶在輸入對話方塊中輸入兩個日期後(日期格式為YYYYMMDD, 如1999年1月12日應輸入為19990112), 程式將判斷兩個日期的先後順序, 以及兩個日期之間的間隔天數(例如1999年1月1日和1999年1月2日之間的間隔是1天。  

    表達異常的分支時 if-else 方式(可以使用衛語句、策略模式或者狀態模式來實現)

    避免後續程式碼維護困難, if-else儘量不要超過3層, 可以嘗試使用衛語句、策略模式或者狀態模式 衛語句: 衛語句就是把複雜的條件表示式拆分成多個條件表示式,比如一個很複雜的表示式,嵌套了好幾層的i

    通過java呼叫VBSVBS執行Excel中的巨集的例子

    (一)  首先需要降低客戶端及伺服器端對於Excel的巨集的安全級別的要求,按照下述的圖示進行操作: (1)進入巨集的安全級別設定功能 (2) 降低巨集的安全級別 (二)  按照下面程式碼編寫VBS程式碼 Option Explicit Dim objXL

    推薦一款阿里開源的 Java 診斷工具到爆!

    Arthas是什麼鬼? Arthas是一款阿里巴巴開源的 Java 線上診斷工具,功能非常強大,可以解決很多線上不方便解決的問題。