【问题标题】:Why use composition? [duplicate]为什么要使用组合? [复制]
【发布时间】:2013-10-04 19:30:58
【问题描述】:

我一直在寻找关于什么可能是组合的简单代码示例的答案。我知道组合和继承的区别,但我无法使用代码弄清楚。

任何关于我为什么应该使用组合的基于比较的示例(使用两种方法)都会非常有帮助。

提前致谢

【问题讨论】:

  • 我想我已经从下面的链接中得到了答案。基本上我关心的是改变基类方法的概念如何影响我们是否应该使用继承或组合。
  • 而且我认为如果我们使用继承并且如果在基类函数中进行任何更改,那么实际调用客户端代码将受到影响。但是如果我们使用组合,更改基类函数将需要我们更改使用它的类。客户端代码将保持不变。另一点是只有在需要使用基类的全部功能时才应该使用继承。我将再次重申,我再次启动此线程的主要关注点与基类功能的更改有关。

标签: design-patterns


【解决方案1】:

您可能想查看 Composition over inheritance

有利于组合而不是继承是一个设计原则, 赋予设计更高的灵活性,赋予业务领域类 并在长期内更稳定的业务领域。 换句话说, HAS-A 可能比 IS-A 关系更好

related post 中查看 aleemb 的答案,他在其中解释了与代码示例的区别

这是一个有用的link,它解释了为什么更喜欢组合而不是继承

虽然组合和继承都允许您重用代码,但继承的缺点之一是它破坏了封装。如果子类的操作依赖于超类的行为,它会突然变得脆弱。当超类的行为发生变化时,子类中的功能可能会被破坏,而不会对其进行任何更改。继承使代码变得脆弱的一个例子是来自 HashSet 的方法 add() 和 addAll()。假设,如果HashSet的addAll()是通过调用add()方法实现的,你写了一个HashSet的子类,在插入HashSet之前对内容进行加密。由于只有一种方法 add(),它可以将对象插入 HashSet,因此您覆盖这些方法并通过覆盖 add() 调用您的 encrypt() 方法。这也自动覆盖了 addAll(),因为 addAll() 是使用 add() 实现的,它看起来非常诱人。如果仔细观察,您会发现这个实现很脆弱,因为它依赖于超类的行为。如果基类想要提高性能并在不调用 add() 方法的情况下实现 addAll(),下面的示例将会中断。

public class EncryptedHashSet extends HashSet{
.....

public boolean add(Object o) {
   return super.add(encrypt(o));
}

}

如果您使用组合来支持继承,您将不会遇到这个问题,并且您的类会更加健壮,因为您不再依赖超类的行为。相反,您将超类方法用于添加部分,您将受益于 addAll() 的任何改进,如下例所示:

public class EncryptedHashSet implements Set{
private HashSet container;

public boolean add(Object o) {
   return container.add(encrypt(o));
}

public boolean addAll(Collection c) {
   return conatainer.add(encrypt(c));
}

.......
}

【讨论】:

    【解决方案2】:

    根本区别在于继承在编译时固定类层次结构,而组合允许在运行时决定组合的类关系。

    使用继承,它使用继承层次结构固定的代码。例如,如果我们从Shape 类继承Circle 类,则Shape 固定为Circle 类的基类。

    假设我们进一步将Shape分类为2DShape3DShape。现在有了继承,Circle 类就不可能从 2DShape 继承。

    使用合成是可能的。因此,您可以在运行时将组合类更改为组合类的任何派生类型。

    【讨论】:

      【解决方案3】:

      我认为 Joshua Bloch 说得最好:Item 16: Favor composition over inheritance

      【讨论】:

      • 你们上面发布的所有答案都非常有帮助。但不知何故,我无法标记所有答案。仍然感谢各位的回复,他们真的很有帮助。还有一件事,我希望你们看看我的回复,在我上面的问题之后发布,让我知道我的理解是否正确。
      猜你喜欢
      • 2013-09-18
      • 2012-09-12
      • 1970-01-01
      • 2019-05-01
      • 2013-12-18
      • 2013-04-21
      • 2013-05-28
      • 2011-05-01
      • 1970-01-01
      相关资源
      最近更新 更多