Java接口设计模式现状
我被一个问题困住了。 我的问题是这样的。 我有一个超类动物和两个亚类人类和鸟类。 我的超级类Animal中有一个fly方法,它将基于Flyable接口为类Human和Bird提供一个实现 我的动物课是这样的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
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(某种东西)当你的超类是一个抽象类时,这种方法就会失败,甚至超类也不应该有可飞行的接口,你建议呢?@RohitSinghAnimal
不应该实现可飞行的Flyable
,因为不是所有的动物都能飞。但如果将来我决定引入一个实现可飞行接口的类FlyWithJetPack呢?您似乎误解了接口实现的概念。您不会创建很多具体的类,比如FlyHigh
或CantFly
,而将它们的实例作为Human
和Bird
的字段Bird
应直接实现Flyable
Human
应该有一个名为jetpack
的字段,该字段的类型为jetpack
。而Jetpack
应该实现Flyable
。不需要带Jetpack的飞行
类@Rohitsingheen超类不应该有可飞行的界面,你建议呢?@RohitSinghAnimal
不应该实现可飞行的,因为不是所有的动物都可以飞行。但是如果将来我决定引入一个类FlyWithJetPack,它将实现可飞行的界面呢