【发布时间】:2014-11-24 14:28:43
【问题描述】:
我有一个带有通用集合(Flavors)的抽象类(Candy)。 Candy 有一个工厂方法来生成它自己的具体实例。它还具有获取适用于具体糖果的通用风味实例并将风味添加到其集合中的方法。
我知道 getter 正在工作,因为如果我从 CandyStore 投射风味,则具体风味特有的方法可以正常工作。但是最后一行,addFlavor(flavor), errs (Eclipse) 在我身上。错误是:“ICandy 类型中的方法 addFlavor(capture#5-of ? extends IFlavor) 不适用于参数 (IFlavor)。”谁能解释一下是怎么回事?
界面:
public interface ICandy <Flavor extends IFlavor> {
public Flavor getFlavorForCandy();
public void addFlavor(Flavor flavor);
}
抽象类:
public abstract class AbstractCandy<Flavor extends IFlavor> implements ICandy<Flavor> {
public static ICandy<? extends IFlavor> buildCandy(String flavor){
if(flavor.equals("Jolly Rancher")
return new JolRanchCandy();
}
public Flavor getFlavorForCandy() {
return (Flavor) new CandyFlavor();
}
public void addFlavor(Flavor flavor) {
... //implemented
}
}
具体类:
public class JolRanchCandy extends AbstractCandy<JolRanchFlavor> {
... //implemented
}
使用者:
public class CandyStore {
private ICandy<? extends IFlavor> candy;
private IFlavor flavor;
public void createCandy() {
candy = AbstractCandy.buildCandy("Jolly Rancher");
flavor = candy.getFlavorForCandy(); //returns a JolRanchFlavor
flavor.setName("Apple"); //etc for creating flavor
candy.addFlavor(flavor); //no luck
}
}
编辑:为清楚起见,JolRanchFlavor extends CandyFlavor implements IJolRanchFlavor 和 CandyFlavor implements IFlavor。
【问题讨论】:
-
您已经声明了
ICandy<? extends IFlavor> candy,并且此声明根本不允许添加任何Flavor。将其声明为ICandy<IFlavor> candy会更好。 -
@LuiggiMendoza 您的建议的问题是
addFlavor采用具体实例Flavor而不是IFlavor。 -
@JohnB 这种方法的问题是......另一个例子,
List<Number> numbers = new ArrayList<>(); numbers.add(new Integer(5));编译和运行没有问题。 -
但是
Number是Integer匹配的接口。请注意addFlavor采用Flavor,它不是接口而是类的泛型类型。比如ICandy <T extends IFlavor>中的T -
[来自下面答案的相同评论] 这是因为您需要
JolRanchCandy覆盖getFlavorForCandy以返回JolRanchFlavor的实例,因为默认实现返回CandyFlavor。
标签: java generics collections interface factory-method