Item35 -- 確定你的public繼承,類比出is-a關係
public繼承是is-a關係,潛在含義就是基類的所有函數在子類中都能用。舉個範例,所有鳥都會飛,但是鴨子不會,所以鴨子不能從鳥public繼承而來。如果一定要用,也要講鳥劃分成會飛的鳥和不會飛的鳥,鴨子從不會飛的鳥公開繼承。
Item36 -- 區分介面繼承和實現繼承
- 聲明一個純虛函數的目的是讓子類只繼承其介面
- 聲明一般(非純)虛函數的目的,是為了讓子類繼承該函數的介面和預設行為
- 聲明非虛函數的目的是為了讓子類繼承函數的介面和實現。且"不變性"淩駕於"變異性"之上,我們不應該在子類重新定義它。
以上三點都是在public繼承的條件下成立。
Item37 -- 絕對不要重新定義繼承而來的非虛擬函數
同條款36的第三點,不變性淩駕於變異性之上
Item38 -- 絕對不要重新定義繼承而來的預設參數值
預設參數是靜態性別,及時採用虛函數進行多態,但是預設參數是不變的,因此重新定義繼承而來的預設參數會導致混淆。
Item39 -- 避免在繼承體系中做向下轉型動作
向下轉型必然導致if then else,而這個可以用虛函數來實現。同樣,當使用過多的switch的時候,也可以考慮利用虛函數進行優雅的實現。回想一個問題,小機器人,根據ewsn四個指令向東向西向南向北走,採用虛函數進行實現。
Item40 -- 通過layering技術來塑造has-a或is-implemented-in-terms-of
layering又稱組合,內含另一類的對象,通過包裹該對象的行為來實現自己的介面。但是這種情況會產生編譯依賴的問題,可以參考條款34.
Item41 -- 區分繼承和模板
模板用來產生一群class,其中對象性別不會影響class的函數行為
繼承應用於一群class身上,其中對象性別會影響class的函數行為
Item42 -- 明智地運用私人繼承
- 如果是私人繼承,編譯器不會隱式的將子類對象轉化成基類對象
- 私人繼承,基類所有函數在子類都變成私人屬性
- 私人繼承意味著根據某物實現,與layering相比,當protected members和虛擬函數牽扯進來會有很大的優越性。
- 私人繼承,子類僅僅是使用了父類中的代碼,他們沒有任何概念上的關係。
Item43 -- 明智地運用多繼承(MI)
- 多繼承會產生模稜兩可,子類調用方法如何兩個父類都有,則必須指明使用的是哪個父類
- 多繼承會產生鑽石型繼承體現,為了使得祖先類只有一份,請在兩個父類繼承祖先的時候採用虛繼承(而這在設計祖先類的時候一般是無法預料到的)
- 可以通過public繼承方式繼承介面,private繼承方式繼承實現,來完成目的
Item44 -- 說出你的意思,並瞭解你所說的每一句話
條款44其實是上面所有的總結