组合和继承是一样的吗? 如果我想实现组合模式,我如何在Java中做到这一点?


当前回答

组合意味着有A 继承意味着IS A

例子:Car有引擎,Car是一辆汽车

在编程中,这被表示为:

class Engine {} // The Engine class.

class Automobile {} // Automobile class which is parent to Car class.

class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class.
  private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member.
}

其他回答

它们完全不同。继承是一种“是-是”关系。作文是“has-a”。

通过使用另一个类C的实例作为类的字段来进行组合,而不是扩展C。java.util就是一个很好的例子,其中组合比继承要好得多。堆栈,它目前扩展了java.util.Vector。现在看来,这是一个大错。堆栈“is-NOT-a”向量;不应该允许任意插入和删除元素。应该是合成。

不幸的是,现在纠正这个设计错误已经太晚了,因为现在更改继承层次结构将破坏与现有代码的兼容性。如果Stack使用组合而不是继承,那么它总是可以被修改为使用另一种数据结构,而不会违反API。

我强烈推荐Josh Bloch的《Effective Java第二版》

项目16:比起继承,更喜欢组合 项目17:设计和文件的继承或禁止

好的面向对象设计不是随意扩展现有的类。你的第一直觉应该是作曲。


参见:

组合与继承:两种基本的类关联方法的比较

继承带来IS-A关系。复合引出HAS-A关系。 策略模式解释了组合应该用于定义特定行为的算法族的情况。典型的例子是实现飞行行为的鸭子类。

public interface Flyable{
 public void fly();
}

public class Duck {
 Flyable fly;

 public Duck(){
  fly = new BackwardFlying();
 }
}

因此,我们可以有多个实现飞行的类 例如:

public class BackwardFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies backward ");
  }
}
public class FastFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies 100 miles/sec");
  }
}

如果是继承的话,我们就会有两个不同的鸟类,它们会反复实现fly函数。所以继承和组合是完全不同的。

两个类之间的继承,其中一个类扩展了另一个类,建立了“IS A”关系。

另一端的组合包含类中另一个类的实例,建立了“Has A”关系。组合在java中是很有用的,因为它在技术上便于多重继承。

继承意味着重用一个类的完整功能,在这里,我的类必须使用超类的所有方法,我的类将与超类titely耦合,在继承的情况下,代码将在两个类中重复。

但是当我们用作文与其他班级进行交流时,我们可以克服这些问题。复合是将另一个类的属性声明到我们想要与之对话的类中。我们想从那个类中得到什么功能可以通过使用那个属性来实现。

我认为这个例子清楚地解释了继承和组合之间的区别。

在本例中,使用继承和组合解决了这个问题。作者注意到;在继承中,父类的更改可能会导致继承它的派生类出现问题。

在这里,您还可以看到使用UML进行继承或组合时在表示上的区别。

http://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should-you-choose-.html