我有一个基类 Plant,其中有两个子类型路径。Fruit extends PlantVegetable extends Plant.FruitVegetable 也是抽象类,然后它们还有其他类,如 Banana extends FruitSpinach 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/

10-10 22:30