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' タイプで初期化する方法は? ここで、引数 foodType と amount を指定して ConcreteFood で初期化しますが、私の目標は ConcreteFood を拡張する T でこのリストを初期化することです。ConcreteFood のすべてのサブクラスは、foodType と food count にアクセスできます。このリストを適切な ConcreteFood サブクラスで初期化し、各 ConcreteFood オブジェクトを foodType および count = 0 で初期化します。どうすればよいですか?

4

3 に答える 3

1

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());
}
于 2013-03-25T15:08:19.990 に答える
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());
    }
  }
}
于 2013-03-25T13:19:56.483 に答える
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 
    }
}

あなたのネーミングはあまり気にしません。「コンクリートフード」?食欲をそそる音ではありません。なぜFoodCategoryではないのですか?

于 2013-03-25T12:44:40.810 に答える