Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 灵活性方面的继承与组合_Java_Inheritance_Composition - Fatal编程技术网

Java 灵活性方面的继承与组合

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() {

我正在阅读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() {
        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();
}
现在,假设我希望这两个鸭子都能以超快模式飞行,我需要对继承进行以下更改:

  • 扩展MallardDuck并创建MallardSuperFastDuck
  • 在应用程序上下文中,将mallardDuck指向MallardSuperFastDuck,而不是mallardDuck
  • 对于合成,我需要几乎相同的步骤:

  • 扩展Flyable并创建新的SuperFastFlyer(实现Flyable)
  • 将indianFlight指向新对象SuperFastFlyer
  • 我无法理解为什么在上述情况下继承不那么灵活。我肯定我没有抓住要点,但我想得太多了才发布了这篇文章

    有人能解释一下我遗漏了什么吗

    另外,据说通过合成,可以在运行时绑定行为。真正地如果我需要新的行为-我必须写一个新的类,再次编译代码。所以这也是编译时

    请解释一下


    谢谢

    这里的折衷不是你可以阅读和理解的东西——你需要获得一些经验,然后它就会变得相当自然。人为地坚持一种或另一种方案,因为这是“正确的方式”,往往会让你感到悲伤。@nachokk这是否意味着上面的代码可以使用继承或组合?另外,Head First还描述了继承时使用接口的副作用,它说的是行为的改变需要你改变子类,我认为这并不总是像上面描述的那样。我认为你永远不应该改变你的接口,这是一个契约。。您始终可以创建一个新接口并扩展到旧接口,这样就不必更改子类、
    open-closed-principle
    ,或者
    separation-interface-principle
    。此外,合成更灵活,因为您可以在运行时更改行为这是事实,请参见非常简单的
    策略模式
    状态模式
    。永远不要更改您的界面???这样可以维持大约15分钟。@HotLicks我的意思是生产代码中永远不要更改,如果我想扩展它,我总是可以创建
    公共接口newInterface extends OldInterface
    ,我的意思是,如果子类不应该更改,就不必更改它们。。对不起,如果我的英语不清楚