我有一个基类 Plant
,其中有两个子类型路径。Fruit extends Plant
和 Vegetable extends Plant.
Fruit
和 Vegetable
也是抽象类,然后它们还有其他类,如 Banana extends Fruit
和 Spinach extends Vegetable
。
现在让我们说例如,一个操作必须通过这些类进行操作,并且有一个操作接口(interface)。
目前的设计如下:
我有一个界面:
abstract class Plant {}
abstract class Fruit extends Plant {}
class Banana extends Fruit {}
public interface PlantWeigher<T extends Plant> {
public int weight(T fruit);
}
然后我有:
public abstract class FruitWeigher<Y extends Fruit> implements PlantWeigher<Y> { }
然后我有具体的类:
public class BananaWeigher extends FruitWeigher<Banana> {
public int weight(Banana fruit);
}
现在,作为刚刚了解Plant的用户,我想获取Weigher的正确实例,然后进行操作。
所以工厂如下:
public class WeigherFactory {
public static PlantWeigher<? extends Plant> getInstance(Plant plant){
// based on some logic on Plant argument, I return, lets say:
return new BananaWeigher();
}
}
所以在用户类中,我调用了以下函数:
PlantWeigher<? extends Plant> instance = WeigherFactory.getInstance(userPlant);
instance.weight(plant); // THIS LINE GIVES AN ERROR
有人可以帮助我了解这里的设计有什么问题,也可以有人建议解决方案。
谢谢。
最佳答案
线路:
PlantWeigher<? extends Plant> instance = WeigherFactory.getInstance(userPlant);
意思是,“我有一个称重器,可以称重
Plant
的一些子类,而不是所有种类的植物”。例如,如果工厂将返回一个 BananaWeigher
,那么尝试用它对 Tomato
进行加权是没有意义的。为了实现你想要的,你应该改变工厂如下:
public class WeigherFactory{
public static <P extends Plant> PlantWeigher<P> getInstance(P plant){
// should return a correct Weigher for the subttype of Plant P
return ...
}
}
然后调用代码将返回如下:
PlantWeigher<Banana> instance =WeigherFactory.getInstance(banana);
instance.weigh(banana)
现在你有一个特定的
PlantWeigher
并且你可以用一个特定的类型调用它或 ,如果您希望能够用任何类型的
Plant
权衡任何类型的 PlantWeigher
,则应该更改后者: public interface PlantWeigher {
public int weight(Plant p);
}
这确保了
PlantWeigher
可以加权任何计划,无论是否有意义。关于Java:接口(interface)和工厂中的泛型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32199509/