设计模式组成还是继承?

时间:2010-03-11 11:55:24

标签: design-patterns

大多数人更喜欢写作继承,

但这样做的重要好处是什么?

6 个答案:

答案 0 :(得分:5)

本文应该给你一个完整的答案: Design Principles from Design Patterns: Composition versus inheritance

我引用了Erich Gamma的直接回答:

  

即使十年之后,我仍然认为这是真的。继承是改变行为的一种很酷的方式。但我们知道它很脆弱,因为子类可以轻松地对其覆盖的方法被调用的上下文进行假设。基类和子类之间存在紧密耦合,因为我将调用插入的子类代码的隐式上下文。组合物具有更好的性质。通过将一些较小的东西插入更大的东西来减少耦合,而较大的对象只是将较小的对象调回来。从API的角度来看,定义一个方法可以被覆盖是一个比定义一个方法可以被调用更强的承诺。

     

在子类中,当您调用覆盖的方法时,可以对超类的内部状态进行假设。当你插入某些行为时,它会更简单。这就是你应该支持作曲的原因。一个常见的误解是组合根本不使用继承。组合使用继承,但通常只是实现一个小接口,而不是从大类继承。 Java监听器习语是一个很好的组合示例。使用侦听器,您可以实现侦听器接口或从所谓的适配器继承。例如,您创建一个侦听器对象并使用Button小部件注册它。没有必要将Button子类化以对事件做出反应。

答案 1 :(得分:1)

答案 2 :(得分:0)

在不支持多重继承的语言中,您不会“烧掉”从另一个类(类型)派生的机会。

此外,它可以是问题域的更合适的建模。

答案 3 :(得分:0)

因为新类没有完全符合可以放在特定“基类”的'继承'层次结构下的东西......

显着的好处:

扩展另一个类的选项是“始终可用”

你不会被束缚于基类的实现和定义

答案 4 :(得分:0)

继承是适合正确情况的好工具,但经常被滥用。

通过优先考虑组合继承,您可以实时交换实现。例如,您可以通过为类提供一个提供行为的接口来编写类。如果该类需要针对不同情况的两种不同实现,那么您就拥有了这种自由。但是,如果你曾经使用过继承,那么你仍然会有你的超类的行为,并且必须在很多地方覆盖它。基本上,合成是一种更灵活的创建对象的模型。

答案 5 :(得分:0)

一些设计模式使用了使用继承实现的接口的compsition。所以组成不排除继承 但是,对所有事物使用继承往往会导致多继承,大类层次结构和许多异常。