在,JSF C++ Coding Standards,中,AV规则87显示了抽象基类的图和作为多继承的实现。
使用形状的经典多态示例:
5,
我的实现方法如下吗?这对我来说似乎不正确。我担心,我错过了设计的目的。传统上,我希望Right_Triangle从Triangle继承。
class Shape{}; // Interface
class Right_Triangle{}; // Impl
class Triangle : public Shape,
private Right_Triangle {}; // D1
最佳答案
您的示例大体上是正确的,并遵循了AV 87的精神。尽管您进行了打错,但实现和公共(public)类应具有相同的“种类”(例如,两者都应为通用三角形) :
class IShape { ... };
class TriangleImpl { ... };
class Triangle : public IShape,
private TriangleImpl { ... };
声称直角三角形是三角形的图是错误,并且是一个常见的误解。直角三角形不是三角形,除非您明确限制对三角形的处理方式(例如,使其变为只读)。三角形可以具有所需的任意边长。从三角形继承的类必须仍然像三角形那样起作用。它被称为Liskov Substitution Principle。
由于您不能在任何地方都使用
RightTriangle
类,因此可以不受限制地使用Triangle
类,使Triangle
不能用作具体类(您不能在三角形上设置边长)-因此,所示的继承层次结构很糟糕设计。类层次结构的设计不一定遵循维恩图,也不应该遵循“日常真理”。长期的软件工程实践表明,坚持使用LSP可获得合理的继承图。
是的,如果教科书中没有提供符合LSP的具体设计,则表明此“直角三角形是三角形”疯狂是错误的。对于形状,
Trilateral
和Quadrilateral
接口(interface)必须是只读的,并且特定的顶点或边缘设置方法只能在派生类中提供,因为它们遵循不同的限制。派生的具体类需要一个平坦的层次结构(Square
不是Rectangle
-如果是,则可以为其设置两个不同的边长!)。同样,就LSP而言,Square
不是Quadrilateral
,因为四边形可以任意放置顶点,等等。关于c++ - C++多重继承实现多态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29103493/