下图是我演讲幻灯片中的示例,我了解 C++
对于有一些红宝石知识的我来说,Vector 就像Array
随机访问,而 Stack 是没有的,所以我似乎继承对我来说是合理的。那么谁能给我一个更简单的例子?或解释我的理解有什么问题?
下图是我演讲幻灯片中的示例,我了解 C++
对于有一些红宝石知识的我来说,Vector 就像Array
随机访问,而 Stack 是没有的,所以我似乎继承对我来说是合理的。那么谁能给我一个更简单的例子?或解释我的理解有什么问题?
这是在这种情况下继承不是一个好主意的原因的关键:
Vector is like Array with random access and Stack is the one without
从广义上讲,继承可以为您提供额外的行为;没有合理的*方法来消除行为。
因此,如果Stack
extendsVector
它将继承Vector
类提供的随机访问行为(和契约),这是您不想要的。
根据is-a**考虑继承。Stack
说 a is-a 有意义Vector
吗?如果没有,那么它不应该扩展Vector
。
Stack
您可以使用 a实现 a 的事实与接口Vector
无关。Stack
正如@Patashu 指出的那样,如果需要,您希望能够在不更改合同的情况下更改实施。例如,也许您想使用链表实现而不是Vector
. 如果你延长Vector
这是不可能的;如果您使用合成,那将非常简单。
*当然,您可以重写方法以删除您不想要的行为,但这会违反Vector
合同并使您的用户感到非常困惑。这就是为什么这样做通常是不合理的。
* *is-a有它自己的缺陷,就像软件架构中的其他任何事情一样:请参阅圆椭圆问题,了解为什么在决定哪个类从什么继承时需要格外小心的一个很好的例子。
从为其他人编写的代码库的角度考虑它会有所帮助,因此必须支持其他人的使用,或者您的代码是否正在使用所述其他代码库。当它只是您的代码时,您可以轻松地进行更改,因为您可以控制一切,但是如果必须支持其他人,您必须了解哪些更改会导致其他人的代码中断。
1)如果你从一个类继承,你必须支持与该类相同的契约。通过契约,我的意思是面向公众的方法形成了一组类可以执行的承诺。如果a)它的合同对您的班级来说很笨拙,这可能会很糟糕 b)您继承的合同的班级从您那里改变。
2)通过组合而不是继承,您可以更改用于类实现的内容,而无需进行任何破坏性的公共更改,因此更快更便宜,就像您决定'我不想将 Vector 用于我的堆栈实现,我想改用 DifferentVector' 假设您的堆栈是 Vector 的子类,它会破坏代码。
3) 另外,即使您没有为向量支持的堆栈使用继承,您仍然可以让 Stack 和 Vector 都实现 ICollection 接口(例如),允许它们可以互换和多态使用,这是首先进行继承的主要优势。