组合和继承是一样的吗? 如果我想实现组合模式,我如何在Java中做到这一点?
当前回答
它们完全不同。继承是一种“是-是”关系。作文是“has-a”。
通过使用另一个类C的实例作为类的字段来进行组合,而不是扩展C。java.util就是一个很好的例子,其中组合比继承要好得多。堆栈,它目前扩展了java.util.Vector。现在看来,这是一个大错。堆栈“is-NOT-a”向量;不应该允许任意插入和删除元素。应该是合成。
不幸的是,现在纠正这个设计错误已经太晚了,因为现在更改继承层次结构将破坏与现有代码的兼容性。如果Stack使用组合而不是继承,那么它总是可以被修改为使用另一种数据结构,而不会违反API。
我强烈推荐Josh Bloch的《Effective Java第二版》
项目16:比起继承,更喜欢组合 项目17:设计和文件的继承或禁止
好的面向对象设计不是随意扩展现有的类。你的第一直觉应该是作曲。
参见:
组合与继承:两种基本的类关联方法的比较
其他回答
继承Vs组合。
继承和组合都用于类行为的可重用性和扩展。
继承主要用在IS-A一类算法编程模型中,关系类型是指相似类型的对象。的例子。
吸尘器是一辆车 Safari是一辆车
这些是Car家族的。
Composition表示HAS-A关系类型。它显示了一个对象的能力,如Duster有五个齿轮,Safari有四个齿轮等。每当我们需要扩展现有类的能力时,就使用复合。例如,我们需要在Duster对象中添加一个齿轮,然后我们必须创建一个齿轮对象,并将其组合到Duster对象中。
除非所有派生类都需要这些功能,否则不应该对基类进行更改。对于这个场景,我们应该使用Composition。如
由类B派生
类A由类C派生
类A由类D派生。
当我们在类A中添加任何功能时,即使类C和类D不需要这些功能,它也可以用于所有子类。对于这个场景,我们需要为这些功能创建一个单独的类,并将其组合到所需的类中(这里是类B)。
下面是例子:
// This is a base class
public abstract class Car
{
//Define prototype
public abstract void color();
public void Gear() {
Console.WriteLine("Car has a four Gear");
}
}
// Here is the use of inheritence
// This Desire class have four gears.
// But we need to add one more gear that is Neutral gear.
public class Desire : Car
{
Neutral obj = null;
public Desire()
{
// Here we are incorporating neutral gear(It is the use of composition).
// Now this class would have five gear.
obj = new Neutral();
obj.NeutralGear();
}
public override void color()
{
Console.WriteLine("This is a white color car");
}
}
// This Safari class have four gears and it is not required the neutral
// gear and hence we don't need to compose here.
public class Safari :Car{
public Safari()
{ }
public override void color()
{
Console.WriteLine("This is a red color car");
}
}
// This class represents the neutral gear and it would be used as a composition.
public class Neutral {
public void NeutralGear() {
Console.WriteLine("This is a Neutral Gear");
}
}
不,两者都不一样。组合遵循“HAS-A”关系,继承遵循“IS-A”关系。组合的最佳例子是战略模式。
两个类之间的继承,其中一个类扩展了另一个类,建立了“IS A”关系。
另一端的组合包含类中另一个类的实例,建立了“Has A”关系。组合在java中是很有用的,因为它在技术上便于多重继承。
继承意味着重用一个类的完整功能,在这里,我的类必须使用超类的所有方法,我的类将与超类titely耦合,在继承的情况下,代码将在两个类中重复。
但是当我们用作文与其他班级进行交流时,我们可以克服这些问题。复合是将另一个类的属性声明到我们想要与之对话的类中。我们想从那个类中得到什么功能可以通过使用那个属性来实现。
它们完全不同。继承是一种“是-是”关系。作文是“has-a”。
通过使用另一个类C的实例作为类的字段来进行组合,而不是扩展C。java.util就是一个很好的例子,其中组合比继承要好得多。堆栈,它目前扩展了java.util.Vector。现在看来,这是一个大错。堆栈“is-NOT-a”向量;不应该允许任意插入和删除元素。应该是合成。
不幸的是,现在纠正这个设计错误已经太晚了,因为现在更改继承层次结构将破坏与现有代码的兼容性。如果Stack使用组合而不是继承,那么它总是可以被修改为使用另一种数据结构,而不会违反API。
我强烈推荐Josh Bloch的《Effective Java第二版》
项目16:比起继承,更喜欢组合 项目17:设计和文件的继承或禁止
好的面向对象设计不是随意扩展现有的类。你的第一直觉应该是作曲。
参见:
组合与继承:两种基本的类关联方法的比较
推荐文章
- 到底是什么导致了堆栈溢出错误?
- 为什么Android工作室说“等待调试器”如果我不调试?
- Java:路径vs文件
- ExecutorService,如何等待所有任务完成
- Maven依赖Servlet 3.0 API?
- 如何在IntelliJ IDEA中添加目录到应用程序运行概要文件中的类路径?
- getter和setter是糟糕的设计吗?相互矛盾的建议
- Android room persistent: AppDatabase_Impl不存在
- Java的String[]在Kotlin中等价于什么?
- Intellij IDEA上的System.out.println()快捷方式
- 使用Spring RestTemplate获取JSON对象列表
- Spring JPA选择特定的列
- URLEncoder不能翻译空格字符
- Java中的super()
- 如何转换JSON字符串映射<字符串,字符串>与杰克逊JSON