组合和继承是一样的吗? 如果我想实现组合模式,我如何在Java中做到这一点?
当前回答
它们完全不同。继承是一种“是-是”关系。作文是“has-a”。
通过使用另一个类C的实例作为类的字段来进行组合,而不是扩展C。java.util就是一个很好的例子,其中组合比继承要好得多。堆栈,它目前扩展了java.util.Vector。现在看来,这是一个大错。堆栈“is-NOT-a”向量;不应该允许任意插入和删除元素。应该是合成。
不幸的是,现在纠正这个设计错误已经太晚了,因为现在更改继承层次结构将破坏与现有代码的兼容性。如果Stack使用组合而不是继承,那么它总是可以被修改为使用另一种数据结构,而不会违反API。
我强烈推荐Josh Bloch的《Effective Java第二版》
项目16:比起继承,更喜欢组合 项目17:设计和文件的继承或禁止
好的面向对象设计不是随意扩展现有的类。你的第一直觉应该是作曲。
参见:
组合与继承:两种基本的类关联方法的比较
其他回答
它们完全不同。继承是一种“是-是”关系。作文是“has-a”。
通过使用另一个类C的实例作为类的字段来进行组合,而不是扩展C。java.util就是一个很好的例子,其中组合比继承要好得多。堆栈,它目前扩展了java.util.Vector。现在看来,这是一个大错。堆栈“is-NOT-a”向量;不应该允许任意插入和删除元素。应该是合成。
不幸的是,现在纠正这个设计错误已经太晚了,因为现在更改继承层次结构将破坏与现有代码的兼容性。如果Stack使用组合而不是继承,那么它总是可以被修改为使用另一种数据结构,而不会违反API。
我强烈推荐Josh Bloch的《Effective Java第二版》
项目16:比起继承,更喜欢组合 项目17:设计和文件的继承或禁止
好的面向对象设计不是随意扩展现有的类。你的第一直觉应该是作曲。
参见:
组合与继承:两种基本的类关联方法的比较
不,两者都不一样。组合遵循“HAS-A”关系,继承遵循“IS-A”关系。组合的最佳例子是战略模式。
继承意味着重用一个类的完整功能,在这里,我的类必须使用超类的所有方法,我的类将与超类titely耦合,在继承的情况下,代码将在两个类中重复。
但是当我们用作文与其他班级进行交流时,我们可以克服这些问题。复合是将另一个类的属性声明到我们想要与之对话的类中。我们想从那个类中得到什么功能可以通过使用那个属性来实现。
合成就像它听起来一样-你通过插入部分来创建一个对象。
这个答案的其余部分错误地基于以下前提。 这是通过接口完成的。 例如,使用上面的Car例子,
Car implements iDrivable, iUsesFuel, iProtectsOccupants
Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic
House implements iProtectsOccupants
Generator implements iUsesFuel
用一些标准的理论组件,你就可以构建你的对象。然后,你的工作就是填写房子如何保护它的居住者,以及汽车如何保护它的居住者。
继承则正好相反。您从一个完整(或半完整)对象开始,然后替换或覆盖您想要更改的各种位。
例如,机动车辆可能带有可燃料方法和驱动方法。您可以保留Fuel方法,因为给摩托车和汽车加油是一样的,但您可以重写Drive方法,因为摩托车的运行方式与汽车非常不同。
通过继承,一些类已经完全实现,而其他类的方法必须重写。在合成中什么都没有给你。(但是你可以通过调用其他类中的方法来实现接口,如果你碰巧有一些东西的话)。
组合被认为是更灵活的,因为如果你有一个像iUsesFuel这样的方法,你可以在其他地方有一个方法(另一个类,另一个项目),它只关心处理可以被燃料的对象,不管它是汽车、船、炉子、烧烤等等。接口要求那些声称实现了该接口的类实际上拥有该接口的全部方法。例如,
iFuelable Interface:
void AddSomeFuel()
void UseSomeFuel()
int percentageFull()
然后你可以在其他地方有一个方法
private void FillHerUp(iFuelable : objectToFill) {
Do while (objectToFill.percentageFull() <= 100) {
objectToFill.AddSomeFuel();
}
奇怪的例子,但它表明这个方法并不关心它在填充什么,因为对象实现了iUsesFuel,它可以被填充。故事结束了。
如果你使用继承,你将需要不同的FillHerUp方法来处理机动车辆和烧烤,除非你有一些相当奇怪的“ObjectThatUsesFuel”基础对象来继承。
组合意味着有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.
}
推荐文章
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么我不能继承静态类?
- 为什么java.util.Set没有get(int index)?
- 合并两个PHP对象的最佳方法是什么?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 设计模式:工厂vs工厂方法vs抽象工厂