“避免继承”的想法从何而来?源自?

发布于 2024-10-17 01:05:00 字数 1539 浏览 2 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

天涯沦落人 2024-10-24 01:05:00

我认为他的意思可能是继承可能被过度使用,即使在组合是更好的解决方案的情况下也是如此。这在多本书中都有讨论,例如

继承是实现代码重用的有效方法,但它并不总是最好的
工作的工具。使用不当会导致软件脆弱。使用安全
包内的继承,其中子类和超类实现
都在同一个程序员的控制之下。使用继承也是安全的
当扩展专门为扩展而设计和记录的类时
(第 17 项)。跨包边界继承普通具体类,
然而,这是危险的。提醒一下,本书使用“继承”一词
意味着实现继承(当一个类扩展另一个类时)。存在的问题
本项中讨论的内容不适用于接口继承(当类实现
接口或一个接口扩展另一个接口的地方)。

与方法调用不同,继承违反了封装 [Snyder86]。
换句话说,子类依赖于其超类的实现细节
其正常功能。超类的实现可能会在发布后发生变化
释放,如果释放,子类可能会崩溃,即使它的代码没有
被感动了。因此,子类必须与其超类同步发展,
除非超类的作者专门设计并记录了它
以达到扩展的目的。

  • Effective C++ 第三版 有几项与此相关:
    • 第 32 项:确保公共继承模型“is-a”。
    • 第 34 条:接口继承和实现继承的区别
    • 第 38 项:模型通过组合“has-a”或“is-implemented-in-term-of”

I think what he might have meant is that inheritance can be overused, even in cases where composition would be a better solution. This is discussed in several books, e.g.

Inheritance is a powerful way to achieve code reuse, but it is not always the best
tool for the job. Used inappropriately, it leads to fragile software. It is safe to use
inheritance within a package, where the subclass and the superclass implementations
are under the control of the same programmers. It is also safe to use inheritance
when extending classes specifically designed and documented for extension
(Item 17). Inheriting from ordinary concrete classes across package boundaries,
however, is dangerous. As a reminder, this book uses the word “inheritance” to
mean implementation inheritance (when one class extends another). The problems
discussed in this item do not apply to interface inheritance (when a class implements
an interface or where one interface extends another).

Unlike method invocation, inheritance violates encapsulation [Snyder86].
In other words, a subclass depends on the implementation details of its superclass
for its proper function. The superclass’s implementation may change from release
to release, and if it does, the subclass may break, even though its code has not
been touched. As a consequence, a subclass must evolve in tandem with its superclass,
unless the superclass’s authors have designed and documented it specifically
for the purpose of being extended.

  • Effective C++ 3rd Edition has several items related to this:
    • Item 32: Make sure public inheritance models "is-a."
    • Item 34: Differentiate between inheritance of interface and inheritance of implementation
    • Item 38: Model "has-a" or "is-implemented-in-terms-of" through composition
一个人的旅程 2024-10-24 01:05:00

并非每次都要避免,但无论何时,当您陷入超类中定义的一组操作时,它都会阻碍灵活性。基本的设计思想是“固定的部分留给继承,可变的部分注入”。

Head First Design Patterns中有一个很好的例子。

假设您决定使用实现 Fly() 的基类来建模鸭子。假设你有一只橡皮鸭,它当然不会飞。您可以使用不执行任何操作的方法重写 Fly() 。但有一天,你添加了 DecoyDuck 并忘记重写 Fly(),结果就会变得一团糟。最好构建注入所需行为的 DecoyDuck(组合优于继承)。

Not to be avoided every time, but it hinders flexibility wherever you are stuck with a defined set of operations from a superclass. The basic design idea is "leave to inheritance the fixed parts and inject the parts subject to change".

In Head First Desing Patterns there is a good example.

Say you decide to model ducks with a base class which implements fly(). Say that you have a RubberDuck, who can't fly, of course. You override fly() with a method that does nothing. But then some day you add DecoyDuck and forget to override fly() and you get a mess. It would have been better to build the DecoyDuck injecting the desired behaviour (composition over inheritance).

停滞 2024-10-24 01:05:00

C++ 中的良好编码实践更喜欢通过聚合进行组合。参见“C++ 编码标准:101 条规则、指南和最佳实践”作者:萨特/亚历山大雷斯库

Good coding practice in C++ prefers composition through aggregation. cf. "C++ Coding Standards: 101 Rules, Guidelines, And Best Practices" by Sutter/Alexandrescu

她比我温柔 2024-10-24 01:05:00

不应“按原样”避免继承。
当您想要定义/描述“是”关系时,应该使用(并且仅使用)继承。

当一个实体“不是”另一个实体时,该实体不应继承另一个实体。
在这种情况下,应使用组合。

Inheritance should not be avoided 'as is'.
Inheritance should be used (and only used) when you want to define / describe an 'is a' relationship.

When an entity 'is not' anotherentity, entity should not inherit from anotherentity.
In such cases, composition should be used.

暖树树初阳… 2024-10-24 01:05:00

继承有助于泛化(在 OOP 术语中是向上转型),而组合有助于行为定义(控制反转 - 或依赖注入)。

应该使用哪一个带来更多好处;但支持组合也使代码更具可扩展性。因此,代码变得“禁止修改,但开放扩展”,因此“HAS-A 比 IS-A 更好”。

有点像你自己是一辆车或拥有一辆车(或没有?)

Inheritance helps generalization (which is upcasting in OOP terms), whereas Composition helps behavior definition (Inversion of Control - or Dependency Injection).

One should use whichever grants more benefit; but favoring Composition also makes the code more extend-able. Thus, the code becomes "closed to modification, but open to extension" and thus "HAS-A is better than IS-A".

Kind of like being a car yourself or owning a car (or not?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文