2

I have been looking for an answer about what could be a simple code example of the composition. I know the differences of composition and inheritance, but I am not able to figure it out using code.

Any comparison based example(using both approaches) about why I should use composition will be very helpful.

Thanks in advance

4

3 回答 3

1

您可能想要检查组合而不是继承

有利于组合而不是继承是一种设计原则,它赋予设计更高的灵活性,从长远来看,赋予业务领域类和更稳定的业务领域。换句话说,HAS-A 可以比 IS-A 关系更好

相关帖子中查看aleemb的答案,他在其中解释了与代码示例的区别

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

尽管组合和继承都允许您重用代码,但继承的缺点之一是它破坏了封装。如果子类的操作依赖于超类的行为,它会突然变得脆弱。当超类的行为发生变化时,子类中的功能可能会被破坏,而不会对其进行任何更改。继承使代码变得脆弱的一个例子是来自 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));
}

.......
}
于 2013-09-28T15:59:58.587 回答
1

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

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

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

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

于 2013-09-28T15:59:20.417 回答
0

我认为 Joshua Bloch 说得最好:第 16 条:偏好组合胜于继承

于 2013-09-28T16:03:59.860 回答