2013-03-25 92 views
3

这是我的课:通用类的初始化

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, 但我的目标是用T来启动这个列表,它扩展了ConcreteFood。 ConcreteFood的每个子类都可以获得食物类型和食物数量。 我只是想用适当的ConcreteFood子类初始化这个列表,并且 init每个ConcreteFood对象的foodType和count = 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?

+0

'ConcreteFood'是误导,我想他是指那些同意基本食品 – A4L 2013-03-25 12:49:16

+0

的专长,但如果是这样的话,为什么不不是扩展接口食物清单? – duffymo 2013-03-25 12:55:53

+0

这是错误开始的地方:) – A4L 2013-03-25 12:57:30

1

你可以使用你的FoodTypeenum作为工厂:

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()); 
    } 
    } 
} 
+0

+1 - 我只是编码完全相同的东西,并想发布它:/。 – A4L 2013-03-25 13:22:38

+0

我想我的FoodSet 类作为通用的,所以我认为你的方式不是我想要实现的。 – friko 2013-03-25 13:35:46

+0

@ A4L - 用“培根”完成?如果不是'Bacon',就不会被认为是相同的! OldCurmudgeon 2013-03-25 13:36:04

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()); 
} 
+0

谢谢赫斯特,我认为这是我需要的:)。 – friko 2013-03-25 17:20:26

+0

@friko如果这对你有用,你能接受答案,所以更容易找到其他人吗? – 2013-03-25 21:26:09