【发布时间】:2020-03-22 00:27:26
【问题描述】:
现实世界的例子
蝙蝠、鸟类、蜻蜓和人类都能够飞行,但通过convergent evolution 已经进化出独立飞行的能力。
适用于 Java
Bat、Bird、Dragonfly 和Human 都实现了.fly() 函数,但不从公共类继承。我需要一个接收Organism 的函数,不知道是Bat、Bird、Dragonfly 还是Human,但知道它具有.fly() 函数。
当前解决方案
public flyBaby(Bat organism){
organism.fly();
}
public flyBaby(Dragonfly organism){
organism.fly();
}
public flyBaby(Bird organism){
organism.fly();
}
public flyBaby(Human organism){
organism.fly();
}
失败的尝试
public <T> void flyBaby(T organism){
organism.fly();
}
public void run(){
Bat fred = new Bat();
fred.infect("corona_virus");
flyBaby(fred);
}
或喜欢
public void flyBaby(Flyable organism){
organism.fly();
}
public void run(){
Bat fred = new Bat();
fred.infect("corona_virus");
flyBaby((Flyable)fred);
}
【问题讨论】:
-
生物进化和 OOP 范式预计不会以这种方式匹配。你为什么要强迫一些有点站不住脚的东西?是的,所有 3 种生物都会飞,但它们的飞行机制完全不同
-
我编写了一个插件,它在 3 个不同的对象
getShape()上具有相同的功能,但这些对象不继承实现getShape()的类 -
显然他们都应该实现一个接口,比如
FlightCapable。如果他们不这样做,那么您正在寻找的是“鸭子打字”,它在 Java 中不存在。你不能仅仅通过模仿一个接口来实现它。你可以使用反射,但你真的不应该。 -
你可以在java中做一些rudimentary duck-typing。编写您自己的
Flying界面并将它们输入鸭式应该可以工作。 (免责声明,我写了这个,但更多的是作为概念证明......没有声称它很棒或任何东西。) -
您也可以让您的插件方法接受
Supplier<Shape>或任何其他此类接口,并使用doThing(this::getShape);调用它。
标签: java templates inheritance casting