没有继承的OOP重用:这个“现实世界”的实用性如何?

时间:2011-02-14 07:14:15

标签: oop inheritance composition

本文介绍了一种有趣的OOP方法:

  

如果对象存在,该怎么办?   封装和沟通   通过消息?如果代码重用有什么用   与继承无关,但是   使用组合,委托,甚至   老式帮手对象或任何   程序员认为合适的技术?   本体论不会消失,但它会消失   与实现脱钩。

没有继承或依赖于类层次结构的重用的想法是我发现最令人震惊的,但这有多可行?

给出了示例但我无法完全了解如何更改当前代码以适应此方法。

这种方法有多可行?或者是否真的不需要更改代码,而是基于场景的方法,即“仅在需要或最佳时使用”?

编辑:哎呀,我忘了链接:这里是link

4 个答案:

答案 0 :(得分:8)

我确信你听说过“总是喜欢构图而不是继承”。

这个前提的基本思想是将具有不同功能的多个对象放在一起以创建一个功能齐全的对象。这应该优先于从彼此无关的不同对象继承功能。

关于这一点的主要论点包含在Liskov Substitution Principle的定义中,并在这张海报中有趣地说明:

Liskov Substitution Principle: If it looks like a duck, quacks like a duck, but needs batteries - you probably have the wrong abstraction

如果你有一个ToyDuck对象,你应该继承哪个对象,从纯粹的继承角度来看?你应该继承鸭子吗?不 - 很可能你应该继承玩具。

Bottomline是你应该为你的代码使用正确的抽象方法 - 无论是继承还是组合。

对于当前对象,请考虑是否应该从继承树中删除对象,并将其仅包含在可以调用和调用的属性中。

答案 1 :(得分:7)

继承不适合代码重用。继承代码重用通常会导致:

  1. 具有必须不在其上调用的继承方法的类(违反Liskov替换原则),这会使程序员感到困惑并导致错误。
  2. 深度层次结构,当可以在十几个或更多类中的任何地方声明时,需要花费大量时间来查找所需的方法。
  3. 通常,继承树的深度不应超过两层或三层,通常只应继承接口和抽象基类。

    然而,为了它而重写现有代码是没有意义的。但是,当您需要修改时,请尽可能切换到合成。这通常允许您以较小的部分修改代码,因为类之间的耦合会更少。

答案 2 :(得分:4)

我只是略过了文本,但它似乎说OO设计始终是关于:继承并不意味着代码重用工具和松散耦合是好的。这已写了几十次之前,请参阅文章底部的链接参考。这并不意味着你应该完全跳过继承,只需要有意义地使用它,并且只有在它有意义的时候才能使用它。文章还说明了这一点。

至于鸭子打字,我发现这些例子和想法都值得怀疑。像这样:

function good (foo) {
  if ( !foo.baz || !foo.quux ) {
    throw new TypeError("We need foo to have baz and quux methods.");
  }
  return foo.baz(foo.quux(10));
}

添加三个新行只是为了报告运行时自动报告的错误有什么意义?

答案 3 :(得分:4)

继承是基本的

没有继承,没有OOP。

原型设计和委托可用于实现继承(如在JavaScript中),这很好,并且在功能上等同于继承

对象,消息和组合但没有继承是基于对象的,而不是面向对象的。 VB5,而不是Java。是的,可以做到;计划编写大量的样板代码来公开接口和转发操作。

那些坚持继承是不必要的,或者它是“坏”的是创建稻草人:很容易想象继承被严重使用的场景; 这不是对工具的反映,而是对工具用户的反映