天天看點

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

 最近一個師弟問某實作是該用對象持有(其實就是組合)還是內建關系實作好。是以就在這裡簡單的淺談一下,僅是個人觀點,僅供參考。如果寫的不對的地方請指出。

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

     繼承是在編譯時刻靜态定義的,即是靜态複用,在編譯後子類和父類的關系就已經确定了。而組合這是運用于複雜的設計,它們之間的關系是在運作時候才确定的,即在對對象沒有建立運作前,整體類是不會知道自己将持有特定接口下的那個實作類。在擴充方面組合比內建更具有廣泛性。

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

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

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

類适配圖:

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

對象适配圖:

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

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

組 合 關 系

繼 承 關 系

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

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

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

缺點:支援擴充,但是往往以增加系統結構的複雜度為代價

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

缺點:不支援動态繼承。在運作時,子類無法選擇不同的父類

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

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

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

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

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

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

本文轉自破狼部落格園部落格,原文連結:http://www.cnblogs.com/whitewolf/archive/2010/05/03/1726519.html,如需轉載請自行聯系原作者

上一篇: UNITY中有Timer