通用类初始化

时间:2013-03-25 12:41:45

标签: java generics initialization

这是我的班级:

public class FoodSet<T extends ConcreteFood>{
    public List<T> food = new ArrayList<T>();
    public FoodSet()
    {
        /*
        *  FoodType is an enum containing food types e.g: rice, pork, beef ...
        */
        for(FoodType foodType : FoodType.values())
        {  
            /*
            * 1(*)
            * /
            food.add( (T)new ConcreteFood(foodType,0) ) 
        }       
    }
}

并且1(*)是问题,如何使用'T'类型初始化此列表? 现在我用ConcreteFood初始化它,给出参数foodType和amount, 但我的目标是使用扩展ConcreteFood的T来初始化此列表。 ConcreteFood的每个子类都可以访问foodType和食物数量。 我只想用适当的ConcreteFood子类初始化这个列表 使用foodType和count = 0初始化每个ConcreteFood对象。 我该怎么办?

3 个答案:

答案 0 :(得分:1)

这不是你想要的。您需要一个工厂类来为您创建ConcreteFood的实例。

public class FoodFactory {
    private static final FoodFactory INSTANCE = new FoodFactory();

    private FoodFactory() {}

    public static FoodFactory getInstance() { return INSTANCE; }

    public Food create(FoodType type) {
       // Put the type checks here 
    }
}

我不在乎你的命名。 “ConcreteFood”?听起来不开胃。为什么不是FoodCategory?

答案 1 :(得分:1)

您可以将FoodType enum用作工厂:

public static class ConcreteFood {
}

public static class Bacon extends ConcreteFood {
};

public static class SavoyCabbage extends ConcreteFood {
};

enum FoodType {
  Pork {
    @Override
    public ConcreteFood makeNew() {
      return new Bacon();
    }
  },
  Cabbage {
    @Override
    public ConcreteFood makeNew() {
      return new SavoyCabbage();
    }
  };

  public abstract ConcreteFood makeNew();
}

public static class FoodSet {
  public List<ConcreteFood> food = new ArrayList<ConcreteFood>();

  public FoodSet() {
    /*
     *  FoodType is an enum containing food types e.g: rice, pork, beef ...
     */
    for (FoodType foodType : FoodType.values()) {
      /*
       * 1(*)
       */
      //food.add((T) new ConcreteFood(foodType, 0)) 
      food.add(foodType.makeNew());
    }
  }
}

答案 2 :(得分:1)

回应OP的回答:你真的不应该这样想。我建议您将正确的混凝土工厂传递给FoodSet

抽象工厂:

public interface FoodFactory<T extends ConcreteFood> {
    public T create(FoodType type);
}

混凝土工厂,ConcreteFood

的每个子类一个
public class BagFoodFactory implements FoodFactory<BagFood> {
    private static final BagFoodFactory INSTANCE = new BagFoodFactory ();

    private BagFoodFactory () {}

    public static FoodFactory<BagFood> getInstance() { return INSTANCE; }

    public BagFood create(FoodType type) {
        return new BagFood(type, 0);
    }
}

FoodSet

中使用工厂
public class FoodSet<T extends ConcreteFood> {
    public List<T> food = new ArrayList<T>();

    public FoodSet(FoodFactory<T> factory) {
        for (FoodType foodType : FoodType.values()) {
            food.add(factory.create(foodType));
        }
    }
}

将正确的工厂传递给构造函数(无论如何你知道你需要哪一个)。

class Sack
{
    public FoodSet<BagFood> bagFoodSet 
            = new FoodSet<BagFood>(BagFoodFactory.getInstance());
}