bra*_*orm 11 java inheritance design-patterns composition
我favor composition over inheritance
在设计模式中一次又一次地听到这个.引用的一些原因是
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
Run Code Online (Sandbox Code Playgroud)
对于像我这样的初学者来说,通过插图来理解遗传和构图在上述方面的不同之处将会很棒.我已经阅读了各种谈论它们的SO链接,但是通过这些关键点的示例对Java初学者来说非常有用.
我认为清楚地理解差异非常重要,而不仅仅是记住要点.
对于初学者来说这个问题很好,我想我应该首先提醒读者什么是继承和组成,然后继续解释究竟Favor Composition over Inheritance
是什么意思.
继承的利弊:
好处:
缺点:
White-box
重用,因为超类的内部细节通常对子类可见.关于这个问题:
当组合松散耦合时,继承是强耦合的
继承会带给你紧耦合,只需对基类进行一次更改就可以打破很多子类.
但是何时使用以及如何检测我们需要继承或组合?
仅在满足以下所有条件时使用继承(Coad规则):
is a special kind of
而不是表达is a role played by a
.继承是编译时确定的,其中组合是运行时
编译时,您的基类代码将添加到每个子类.
继承打破了封装,而组合则没有
是.现在你看到了继承的缺点.
底线是:
确保继承模型是is-a关系
我的主要指导思想是只有当子类是超类时才应该使用继承.在上面的例子中,Apple
很可能是-a Fruit
,所以我倾向于使用继承.
当你认为你有一个is-a关系时,问一个自己的一个重要问题是,这是一个关系在整个应用程序的整个生命周期中是不变的,幸运的是,代码的生命周期.例如,你可能认为Employee
a-a Person
,当真正Employee
代表a Person
扮演部分时间的角色时.如果这个人失业怎么办?如果这个人既是a Employee
又是a Supervisor
?这种无常的关系通常应该用构图来建模.
不要仅仅为了获得代码重用而使用继承 如果您真正想要的只是重用代码并且看不到任何关系,请使用组合.
不要仅仅为了获得多态性而使用继承
如果您真正想要的只是多态,但没有自然的is-a关系,请使用带接口的组合.
赞成组合Over Inheritance :)
我直接从javaworld中取得了它.
继承是在代码中使用具体类的扩展来表达的。一旦你编写了它,你就不能在不重写类的情况下更改它。我只能通过修改代码来改变。
public class Foo {
public void doSomething() { System.out.println("I'm a Foo"); }
}
public class Bar extends Foo {
public void doSomething() { super.doSomething(); }
}
Run Code Online (Sandbox Code Playgroud)
我只能Bar
通过修改一个或两个类来改变它的作用。
组合通常是基于接口的,这意味着您指定完成什么,而不是如何完成。您只需更改接口的实现即可更改方式,而不会影响客户端。
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(); }
}
Run Code Online (Sandbox Code Playgroud)
Bar
在这种情况下,我可以简单地通过传递接口的不同实现来更改行为Foo
。
这是鲍勃·马丁的坚实原则之一:开放/封闭原则。