繼承和麵向物件設計
阿新 • • 發佈:2018-12-22
繼承與面向物件設計
32. 確定你的public繼承塑模出is-a關係
- "public繼承"意味is-a.適用於base classes身上的每一件事情一定也適用於derived classes身上,因為每一個derived class物件也都是一個base class物件
33. 避免遮掩繼承而來的名稱
- derived classes 內的名稱會遮掩base classes 內的名稱.在public繼承下從來沒有人希望如此.
- 為了讓被遮掩的名稱再見天日,可使用using 宣告式或轉交(forwardign functions).
34. 區別介面繼承和實現繼承
- 介面繼承和實現繼承不同.在public繼承之下,derived classes 總得繼承base class的介面.
- pure virtual函式只具體指定介面繼承
- 簡樸的(非純)impure virtual 函式集體指定介面繼承集預設實現繼承
- non-virtual 函式具體指定介面繼承以及強制性實現繼承
35. 考慮virtual函式以外的其他選擇
- virtual 函式的替代方案包括NVI手法及Strategy設計模式的多種形式.NVI手法自身是一個特殊形式的Template Method設計模式.
- 將機能從成員函式移到class外部函式,帶來一個缺點是,非成員函式無法訪問class 的non-public成員
- trl::function 物件的行為就像一般函式指標.這樣的物件可接納"與給定之目標籤名式(target signature)相容"的所有可呼叫物(callable entities).
36.絕不重新定義繼承而來的non-virtual函式
- 絕對不要重新定義繼承而來的non-virtual函式
37.絕不重新定義繼承而來的預設引數值
- 絕對不要重新定義一個繼承而來的預設引數值,因為預設引數值都是靜態繫結,而virtual函式--你唯一應該覆寫的東西--卻是動態繫結
38.通過複合塑模出has-a 或"根據某物實現出"
- 複合(composition)的意義和public繼承完全不同
- 在應用域(application domain),複合意味著has-a(有一個).在實現域(implementation domain),複合意味is-implemented-in-terms-of(根據某物實現出)
39. 明智而審慎地使用private 繼承
- private 繼承意味is-implemented-in-terms-of (根據某物實現出).它通過比複合(composition)的級別低.但是當derived class需要訪問protected base class的成員,或需要重新定義繼承而來的virtual函式時,這麼設計是合理的.
- 和複合(composition)不同,private 繼承可以造成empty base 最優化.這對致力於"物件尺寸最小化"的程式庫開發者而言,可能很重要
40. 明智而審慎地使用多重繼承
多重繼承比單一繼承複雜.它可能導致新的歧義性,以及對virtual繼承的需要
virtual 繼承會增加大小,速度,初始化(及賦值)複雜度等等成本.如果virtual base classes 不帶任何資料,將是最具實用價值的情況
多重繼承的確與正當用途.其中一個情節設計"public 繼承某個Interface class"和"private 繼承某個協助實現的class"的兩相組合.