面向對象之繼承和組合淺談

     首先它們都是實現系統功能重用,代碼複用的最常用的有效的設計技巧,都是在設計模式中的基礎結構。相信大家已瞭解的,類繼承允許我們根據自己的實現來覆蓋重寫父類的實現細節,父類的實現對於子類是可見的,所以我們一般稱之爲白盒複用。對象持有(其實就是組合)要求建立一個號的接口,但是整體類和部分類之間不會去關心各自的實現細節,即它們之間的實現細節是不可見的,故成爲黑盒複用。

     繼承是在編譯時刻靜態定義的,即是靜態複用,在編譯後子類和父類的關係就已經確定了。而組合這是運用於複雜的設計,它們之間的關係是在運行時候才確定的,即在對對象沒有創建運行前,整體類是不會知道自己將持有特定接口下的那個實現類。在擴展方面組合比集成更具有廣泛性。

    繼承中父類定義了子類的部分實現,而子類中又會重寫這些實現,修改父類的實現,設計模式中認爲這是一種破壞了父類的封裝性的表現。這個結構導致結果是父類實現的任何變化,必然導致子類的改變。然而組合這不會出現這種現象。

    對象的組合還有一個優點就是有助於保持每個類被封裝,並被集中在單個任務上(類設計的單一原則)。這樣類的層次結構不會擴大,一般不會出現不可控的龐然大類。而累的繼承就可能出來這些問題,所以一般編碼規範都要求類的層次結構不要超過3層。組合是大型系統軟件實現即插即用時的首選方式。

   在設計模式中這兩個概念同時出現的地方就是Adapter模式:對象適配(組合)和類適配(繼承)。一般我們提倡用對象適配而不是類適配。基於上面的原因。還有就是在我們的Java和.NET這些完全面向對象的語言而言類的繼承是單繼承,取消了C++等的多繼承。下面放兩個這兩種方式的UML圖:

類適配圖:

 

    clip_image002

對象適配圖:

clip_image002[9]

 

     最後還說一句,“優先使用對象組合,而不是繼承”是面向對象設計的第二原則。但並不是說什麼都設計都用組合,只是優先考慮組合,更不是說繼承即使不好的設計,應該用組合,應爲他們之間也有各自的優勢。下面是他們之間的優缺點比比較表:

組 合 關 系

繼 承 關 系

優點:不破壞封裝,整體類與局部類之間鬆耦合,彼此相對獨立

缺點:破壞封裝,子類與父類之間緊密耦合,子類依賴於父類的實現,子類缺乏獨立性

優點:具有較好的可擴展性

缺點:支持擴展,但是往往以增加系統結構的複雜度爲代價

優點:支持動態組合。在運行時,整體對象可以選擇不同類型的局部對象

缺點:不支持動態繼承。在運行時,子類無法選擇不同的父類

優點:整體類可以對局部類進行包裝,封裝局部類的接口,提供新的接口

缺點:子類不能改變父類的接口

缺點:整體類不能自動獲得和局部類同樣的接口

優點:子類能自動繼承父類的接口

缺點:創建整體類的對象時,需要創建所有局部類的對象

優點:創建子類的對象時,無須創建父類的對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章