why inheritance is strongly coupled where as composition is loosely coupled in Java?
我在设计模式中一次又一次地听到这个
1 2 3 4 | 1)Inheritance is strongly coupled where as composition is loosely coupled 2) Inheritance is compile time determined where as composition is run-time 3)Inheritance breaks encapsulation where as composition does not 4) anything else I am not aware of |
对于像我这样的初学者来说,通过举例说明继承和构图在上述几点上的不同,这将是非常好的。我已经阅读了很多关于它们的链接,但是通过这些关键点的例子对Java初学者来说是很好的。
我认为清楚地理解差异比仅仅记住要点是非常重要的。
对于初学者来说,这个问题很好,也很重要,我认为我应该首先提醒读者什么是继承和组合,然后继续解释
优势:
- 动态结合和多态性的主要好处之一是它们可以帮助使代码更容易更改。
- 新的实现很容易,因为它大部分是继承的。很容易修改或扩展正在重用的实现。
缺点:
- 中断封装,因为它向实现公开子类超级级的细节。
- 由于超级类的内部细节通常是子类可见。
- 如果超类更改。从超类继承的实现可以运行时不更改。
关于问题:
Inheritance is strongly coupled where as composition is loosely coupled
继承将给您带来紧密耦合,只需对基类进行一次更改就可以破坏许多子类。但何时使用以及如何检测我们需要继承或组合?仅当满足以下所有条件时才使用继承(COAD规则):
Inheritance is compile time determined where as composition is run-time
编译时,您的基类代码将添加到每个子类中。
Inheritance breaks encapsulation where as composition does not
对。现在你看到了继承的缺点。
底线是:
确保继承为IS-A关系建模我的主要指导思想是继承只能在子类是超类时使用。在上面的例子中,
当您认为您拥有IS-A关系时,需要问自己的一个重要问题是,这种关系是否会在应用程序的整个生命周期中保持不变,如果幸运的话,还会在代码的生命周期中保持不变。例如,你可能认为一个
不要使用继承来获得代码重用如果您真正想要的只是重用代码,而不存在所谓的关系,那么就使用组合。
不要使用继承来获取多态性如果您真正想要的只是多态性,但没有自然的IS-A关系,那么就使用组合和接口。有利于组合而非继承:)
我直接从爪哇世界拿的。
继承用代码表示,具体类使用扩展。一旦你写了它,你就不能在不重写类的情况下更改它。我只能通过修改代码来更改。
1 2 3 4 5 6 7 | public class Foo { public void doSomething() { System.out.println("I'm a Foo"); } } public class Bar extends Foo { public void doSomething() { super.doSomething(); } } |
我只能通过修改一个或两个类来更改
组合通常是基于接口的,这意味着您要指定要做什么,而不是如何做。只需更改接口的实现,就可以在不影响客户端的情况下更改方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public interface Foo { void doSomething(); } public class FooImpl implements Foo { public void doSomething() { System.out.println("I'm a Foo"); } } public class Bar implements Foo { private Foo foo; public Bar(Foo f) { this.foo = f; } public void doSomething() { this.foo.doSomething(); } } |
在这种情况下,我可以通过传递不同的
这是鲍勃·马丁的坚实原则之一:开放/封闭原则。