預設是Private繼承。
建構函式初始設定式表允許顯式調用成員對象的建構函式。
內建類型可以像是有單個建構函式的對象一樣初始化。如 int i; i(123);但它並不是真的有建構函式。
建構函式調用順序: 先調用基類建構函式,然後調用成員物件建構函數。成員函數建構函式調用順序按聲明順序。
解構函式調用順序: (和建構函式相反)
名字隱藏:在衍生類別中重定義的函數名會掩蓋所有基類版本。
非自動繼承的函數:構造/解構函式不能被繼承,operator = 也不能被繼承。
繼承和組合都能把子物件放在新類中,都使用建構函式的初始設定式去構造子物件。
is-a用繼承表達,has-a用組合表達。
繼承也就是取一個已存在的類,並製作它的一個專門的版本。
對viod指標調用delete,它只釋放記憶體而不調用解構函式。
用組合還是繼承,判斷方法之一是確認:是否需要新類向上映射。
任何向上映射都會損失對象的類型資訊。
***************《物件導向之繼承和組合淺談》*********************
from: http://www.cnblogs.com/whitewolf/archive/2010/05/03/1726519.html
最近一個師弟問某實現是該用對象持有(其實就是組合)還是整合關係實現好。所以就在這裡簡單的淺談一下,僅是個人觀點,僅供參考。如果寫的不對的地方請指出。
首先它們都是實現系統功能重用,代碼複用的最常用的有效設計技巧,都是在設計模式中的基礎結構。相信大家已瞭解的,類繼承允許我們根據自己的實現來覆蓋重寫父類的實現細節,父類的實現對於子類是可見的,所以我們一般稱之為白盒複用。對象持有(其實就是組合)要求建立一個號的介面,但是整體類和部分類之間不會去關心各自的實現細節,即它們之間的實現細節是不可見的,故成為黑盒複用。
繼承是在編譯時間刻靜態定義的,即是靜態複用,在編譯後子類和父類的關係就已經確定了。而組合這是運用於複雜的設計,它們之間的關係是在運行時候才確定的, 即在對對象沒有建立運行前,整體類是不會知道自己將持有特定介面下的那個實作類別。在擴充方面組合比整合更具有廣泛性。
繼承中父類定義了子類的部分實現,而子類中又會重寫這些實現,修改父類的實現,設計模式中認為這是一種破壞了父類的封裝性的表現。這個結構導致結果是父類實現的任何變化,必然導致子類的改變。然而組合這不會出現這種現象。
對象的組合還有一個優點就是有助於保持每個類被封裝,並被集中在單個任務上(類設計的單一原則)。這樣類的階層不會擴大,一般不會出現不可控的龐然大 類。而累的繼承就可能出來這些問題,所以一般編碼規範都要求類的階層不要超過3層。組合是大型系統軟體實現隨插即用時的首選方式。
在設計模式中這兩個概念同時出現的地方就是Adapter模式:對象適配(組合)和類適配(繼承)。一般我們提倡用對象適配而不是類適配。基於上面的原 因。還有就是在我們的Java和.NET這些完全物件導向的語言而言類的繼承是單繼承,取消了C++等的多繼承。下面放兩個這兩種方式的UML圖:
類適配圖:
對象適配圖:
最後還說一句,“優先使用對象組合,而不是繼承”是物件導向設計的第二原則。但並不是說什麼都設計都用組合,只是優先考慮組合,更不是說繼承即使不好的設計,應該用組合,應為他們之間也有各自的優勢。下面是他們之間的優缺點比比較表:
組 合 關 系 |
繼 承 關 系 |
優點:不破壞封裝,整體類與局部類之間松耦合,彼此相對獨立 |
缺點:破壞封裝,子類與父類之間緊密耦合,子類依賴於父類的實現,子類缺乏獨立性 |
優點:具有較好的可擴充性 |
缺點:支援擴充,但是往往以增加系統結構的複雜度為代價 |
優點:支援動態組合。在運行時,整體對象可以選擇不同類型的局部對象 |
缺點:不支援動態繼承。在運行時,子類無法選擇不同的父類 |
優點:整體類可以對局部類進行封裝,封裝局部類的介面,提供新的介面 |
缺點:子類不能改變父類的介面 |
缺點:整體類不能自動獲得和局部類同樣的介面 |
優點:子類能自動繼承父類的介面 |
缺點:建立整體類的對象時,需要建立所有局部類的對象 |
優點:建立子類的對象時,無須建立父類的對象 |