簡體   English   中英

C ++多重繼承實現多態

[英]C++ Multiple Inheritance to Implement Polymorphism

JSF C ++編碼標准中 ,AV規則87顯示了抽象基類的圖和作為多重繼承的實現。

  1. 該圖試圖顯示什么?

  2. 在此示例中,私有/保護繼承的目的是什么?

  3. 如何將實現創建為基類?

  4. AV規則87的圖表顯示D1從impl繼承; 這是否意味着與接口無關的其他實現?

AV規則87

層次結構應基於抽象類。 參見Stroustrup 2,12.5。

基本原理:基於抽象類的層次結構傾向於將設計重點放在產生干凈的接口,將實現細節保留在接口之外,並最小化編譯依賴性,同時允許替代實現共存。 有關示例,請參閱附錄A中的AV規則87。

...

附錄A-AV規則87

基於抽象類的層次結構是首選。 因此,在圖頂部的層次結構比在圖底部的層次結構更可取。 JSF 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的具體設計,那說明“直角三角形就是三角形”的精神錯亂是錯誤的 對於形狀, TrilateralQuadrilateral界面必須是只讀的,並且特定的頂點或邊設置方法只能在派生類中提供,因為它們遵循不同的限制。 派生的具體類需要一個平坦的層次結構( Square不是Rectangle -如果是Rectangle ,則可以為其設置兩個不同的邊長!)。 同樣,就LSP而言, Square不是Quadrilateral ,因為四邊形可以任意放置頂點,等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM