Reputation: 607
This is my class:
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) )
}
}
}
And in 1(*) is the problem, how to init this list, with 'T' type ? Now I init it with ConcreteFood, giving as argument foodType and amount, but my goal is to init this list with T that extends ConcreteFood. Every subclass of ConcreteFood has access to foodType and food count. I just would to init this list with apropriate ConcreteFood subclass and init each ConcreteFood object with foodType and count = 0. How should I do it ?
Upvotes: 3
Views: 1134
Reputation: 13177
In response to OP's answer: you really shouldn't want it this way. I would propose that you pass the correct concrete factory to your FoodSet
as well.
Abstract factory:
public interface FoodFactory<T extends ConcreteFood> {
public T create(FoodType type);
}
Concrete factory, one per subclass of 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);
}
}
Use the factory in your 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));
}
}
}
Pass the correct factory to the constructor (you know which one you need here anyway).
class Sack
{
public FoodSet<BagFood> bagFoodSet
= new FoodSet<BagFood>(BagFoodFactory.getInstance());
}
Upvotes: 1
Reputation: 65813
You could use your FoodType
enum
as a factory:
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());
}
}
}
Upvotes: 1
Reputation: 308743
This isn't what you want. You need a factory class to create instances of ConcreteFood for you.
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
}
}
I don't care for your naming much. "ConcreteFood"? Doesn't sound appetizing. Why not FoodCategory?
Upvotes: 1