[英]C++ Multiple Inheritance to Implement Polymorphism
在JSF C ++編碼標准中 ,AV規則87顯示了抽象基類的圖和作為多重繼承的實現。
該圖試圖顯示什么?
在此示例中,私有/保護繼承的目的是什么?
如何將實現創建為基類?
AV規則87的圖表顯示D1從impl繼承; 這是否意味着與接口無關的其他實現?
AV規則87
層次結構應基於抽象類。 參見Stroustrup 2,12.5。
基本原理:基於抽象類的層次結構傾向於將設計重點放在產生干凈的接口,將實現細節保留在接口之外,並最小化編譯依賴性,同時允許替代實現共存。 有關示例,請參閱附錄A中的AV規則87。
...
附錄A-AV規則87
基於抽象類的層次結構是首選。 因此,在圖頂部的層次結構比在圖底部的層次結構更可取。
使用形狀的經典多態示例:
5.我的實現方法如下嗎? 這對我來說似乎不正確。 我擔心,我錯過了設計的目的。 傳統上,我希望Right_Triangle從Triangle繼承。
class Shape{}; // Interface
class Right_Triangle{}; // Impl
class Triangle : public Shape,
private Right_Triangle {}; // D1
直角三角形是三角形,因此繼承是相反的。
在您的示例中,根據編碼規則,Shape必須是抽象類。 因此shape只能聲明純虛函數,例如Print(),Load(),rotate(),...
要從另一個實現(形狀層次結構旁邊)繼承,則不應使用公共繼承。
您的示例大體上是正確的,並遵循了AV 87的精神。盡管您輸入了錯字,但實現和公共類應具有相同的“種類”(例如,兩者都應為通用三角形) :
class IShape { ... };
class TriangleImpl { ... };
class Triangle : public IShape,
private TriangleImpl { ... };
聲稱直角三角形是三角形的圖是錯誤的 ,並且是一種常見的誤解。 直角三角形不是三角形,除非您明確限制對三角形的處理方式(例如,使其變為只讀)。 三角形可以具有所需的任意邊長。 從三角形繼承的類必須仍然像三角形那樣工作。 這就是所謂的Liskov替代原理 。
由於您不能在任何地方都使用RightTriangle
類,因此可以無限制地使用Triangle
類,使Triangle
作為具體類使用(您不能在三角形上設置邊長)-因此,所示的繼承層次結構只是不好的設計。
類層次結構的設計不一定遵循維恩圖,也不應該遵循“日常真理”。 長期的軟件工程實踐表明,堅持使用LSP可獲得合理的繼承圖。
是的,如果教科書沒有提供滿足LSP的具體設計,那說明“直角三角形就是三角形”的精神錯亂是錯誤的 。 對於形狀, Trilateral
和Quadrilateral
界面必須是只讀的,並且特定的頂點或邊設置方法只能在派生類中提供,因為它們遵循不同的限制。 派生的具體類需要一個平坦的層次結構( Square
不是Rectangle
-如果是Rectangle
,則可以為其設置兩個不同的邊長!)。 同樣,就LSP而言, Square
不是Quadrilateral
,因為四邊形可以任意放置頂點,等等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.