Java 灵活性方面的继承与组合
我正在阅读Head-First设计模式,反对继承的一点是,它硬编码了as组合更灵活的行为。我还不能完全理解它。考虑下面的类:Java 灵活性方面的继承与组合,java,inheritance,composition,Java,Inheritance,Composition,我正在阅读Head-First设计模式,反对继承的一点是,它硬编码了as组合更灵活的行为。我还不能完全理解它。考虑下面的类: interface Flyable{ void fly(); } // Imagine this duck is exposed as a Spring bean named "mallardDuck" : class MallardDuck implements Flyable { @Override public void fly() {
interface Flyable{
void fly();
}
// Imagine this duck is exposed as a Spring bean named "mallardDuck" :
class MallardDuck implements Flyable {
@Override
public void fly() {
System.out.println("Flying slowly");
}
}
class IndianDuck {
Flyable f;
public void setF(Flyable f) {
this.f = f;
}
public void fly() {
f.fly();
}
}
// Imagine this duck is exposed as a Spring bean named "indianFlight" :
class FlyCautiously implements Flyable {
@Override
public void fly() {
System.out.println("Flying cautiously");
}
}
因此,印度鸭使用合成,而绿头鸭使用遗传。考虑以下客户:
public static void main(String[] args) {
// Inheritance:
Flyable f = (Flyable) context.getBean("mallardDuck"); // Use of Spring
f.fly();
// Composition
IndianDuck d = new IndianDuck();
Flyable f = (Flyable) context.getBean("indianFlight");
d.setF(f);
d.fly();
}
现在,假设我希望这两个鸭子都能以超快模式飞行,我需要对继承进行以下更改:
谢谢这里的折衷不是你可以阅读和理解的东西——你需要获得一些经验,然后它就会变得相当自然。人为地坚持一种或另一种方案,因为这是“正确的方式”,往往会让你感到悲伤。@nachokk这是否意味着上面的代码可以使用继承或组合?另外,Head First还描述了继承时使用接口的副作用,它说的是行为的改变需要你改变子类,我认为这并不总是像上面描述的那样。我认为你永远不应该改变你的接口,这是一个契约。。您始终可以创建一个新接口并扩展到旧接口,这样就不必更改子类、
open-closed-principle
,或者separation-interface-principle
。此外,合成更灵活,因为您可以在运行时更改行为这是事实,请参见非常简单的策略模式
或状态模式
。永远不要更改您的界面???这样可以维持大约15分钟。@HotLicks我的意思是生产代码中永远不要更改,如果我想扩展它,我总是可以创建公共接口newInterface extends OldInterface
,我的意思是,如果子类不应该更改,就不必更改它们。。对不起,如果我的英语不清楚