Java接口设计模式现状

Java接口设计模式现状,java,inheritance,design-patterns,interface,gang-of-four,Java,Inheritance,Design Patterns,Interface,Gang Of Four,我被一个问题困住了。 我的问题是这样的。 我有一个超类动物和两个亚类人类和鸟类。 我的超级类Animal中有一个fly方法,它将基于Flyable接口为类Human和Bird提供一个实现 我的动物课是这样的 public class`Animal{ public Flyable flyable; public void fly() { flyable.fly(); } } 人类阶级是这样的 class Human extends An

我被一个问题困住了。 我的问题是这样的。 我有一个超类动物和两个亚类人类和鸟类。 我的超级类Animal中有一个fly方法,它将基于Flyable接口为类Human和Bird提供一个实现

我的动物课是这样的

public class`Animal{

    public Flyable flyable;

    public void fly()
    {
        flyable.fly();
    } 

 } 
人类阶级是这样的

class Human extends Animal {

  Flyable flyable;

  public Human()
  {
   flyable = new CantFly();
  }

}
鸟类看起来像这样

class Bird extends Animal {

      Flyable flyable;

      public Bird()
      {
       flyable = new FlyHigh();
      }

    }
接口如下所示

public interface Flyable {
   public void fly();
}

public class CantFly implements Flyable{

    @Override
    public void fly()
    {
    Sysout("cant fly");
    }
当我打电话时

它给了我NullPointerException

我错过了什么?
我在假设。因为我调用了new Human(),它初始化了超类Animal中的可飞行接口。我错了吗

我通过改变方法的设计解决了这个问题。
fly(Flyable Flyable)。所以我不想要那种设计方案。 我记得当我为一个应用程序实现搜索算法时遇到了这个问题,该应用程序将提供一个结果列表,但列表项将具有不同的
用户界面,
https调用不同的终端URL,
正在解析JSON,
映射到不同的POJO类。

遗憾的是,我不得不用我提到的另一种方法来解决这个问题。

人类
继承自
动物
,因此它的所有字段都隐式地“复制”自
动物
。因此,您不需要在
Human
Bird
中再次声明
flyable

但你做到了。这会导致子类中新的
可飞行的
字段隐藏在
动物
中声明的原始字段。因此,当您这样做时:

flyable = new CantFly();
人类
中,您将为
人类
中的
可飞行
赋值,而不是
动物
中的
可飞行

然后你做了这个:

Animal me = new Human();
me.fly();
Animal
中的
fly
使用在
Animal
类中声明的字段
flyable
,该字段尚未分配(您仅在
Human
中分配了
flyable
)!因此,出现了NPE

要解决此问题,只需删除
Animal
子类中的所有
flyable
字段。这样,只有一个可飞行的
字段


我觉得这个设计有点奇怪<代码>人类
不能飞行,因此它不应该真正有一个可飞行的字段。事实上,任何东西都不应该有一个可飞行的
字段。在这三个类中,只有
Bird
应该实现
Flyable
Human
继承自
Animal
,因此它的所有字段都隐式地“复制”自
Animal
。因此,您不需要在
Human
Bird
中再次声明
flyable

但你做到了。这会导致子类中新的
可飞行的
字段隐藏在
动物
中声明的原始字段。因此,当您这样做时:

flyable = new CantFly();
人类
中,您将为
人类
中的
可飞行
赋值,而不是
动物
中的
可飞行

然后你做了这个:

Animal me = new Human();
me.fly();
Animal
中的
fly
使用在
Animal
类中声明的字段
flyable
,该字段尚未分配(您仅在
Human
中分配了
flyable
)!因此,出现了NPE

要解决此问题,只需删除
Animal
子类中的所有
flyable
字段。这样,只有一个可飞行的
字段


我觉得这个设计有点奇怪<代码>人类
不能飞行,因此它不应该真正有一个可飞行的
字段。事实上,任何东西都不应该有一个可飞行的
字段。在这3个类中,只有
Bird
应该实现
Flyable

为什么在父类和子类中有
Flyable
字段?复制有什么意义呢?在超类中调用Flyable接口的方法。并在子类中初始化flyable。你认为这是错误的方法吗?是的,那是错误的。如果您需要父类中的字段,那么将初始化传递给该类(例如,
super(new CantFly());
)。但是我的超类在构造函数中没有任何参数。我认为super(某种东西)当您的超类是抽象类时,这种方法将失败。为什么在父类和子类中有
flyable
字段?复制有什么意义呢?在超类中调用Flyable接口的方法。并在子类中初始化flyable。你认为这是错误的方法吗?是的,那是错误的。如果您需要父类中的字段,那么将初始化传递给该类(例如,
super(new CantFly());
)。但是我的超类在构造函数中没有任何参数。我认为super(某种东西)当你的超类是一个抽象类时,这种方法就会失败,甚至超类也不应该有可飞行的接口,你建议呢?@RohitSingh
Animal
不应该实现可飞行的
Flyable
,因为不是所有的动物都能飞。但如果将来我决定引入一个实现可飞行接口的类FlyWithJetPack呢?您似乎误解了接口实现的概念。您不会创建很多具体的类,比如
FlyHigh
CantFly
,而将它们的实例作为
Human
Bird
的字段
Bird
应直接实现
Flyable
Human
应该有一个名为
jetpack
的字段,该字段的类型为
jetpack
。而
Jetpack
应该实现
Flyable
。不需要带Jetpack的
飞行
类@Rohitsingheen超类不应该有可飞行的界面,你建议呢?@RohitSingh
Animal
不应该实现可飞行的,因为不是所有的动物都可以飞行。但是如果将来我决定引入一个类FlyWithJetPack,它将实现可飞行的界面呢