如何对列表使用子类型多态和泛型?

时间:2019-03-27 03:22:52

标签: generics inheritance java-8

我正在学习Java,并且已阅读有关继承和子类型多态性的知识。现在,我才刚刚开始学习泛型,并且试图将各个部分放在一起,但被卡住了。

假设我有一个abstract父类AbstractEdibles,并且有两个孩子extend来自其中:FoodDrink。另外,我有一个Store,其中有两个List:一个用于存储Food,另一个用于存储Drink

现在,我希望我的Store能够有某种行为,例如增加其库存。 我想要的方法是定义一种方法来接收产品并将其放在适当的列表中。如果是Food类型,请将其放入食物清单。如果类型为Drink,请将其放入饮料清单。

我确定我需要使用泛型和子类型多态性。这是我的代码段:

public class Store {

  private List<AbstractEdible> foodStock = new ArrayList<>();
  private List<AbstractEdible> drinkStock = new ArrayList<>();

  /**
   * A constructor for a new store inventory that has food and drink.
   *
   * @param foodStock   the list of food items in stock
   * @param drinkStock  the list of drink items in stock
   */
  public Store(List<AbstractEdible> foodStock, List<AbstractEdible> drinkStock) {
    this.foodStock = foodStock;
    this.drinkStock = drinkStock;
  }

  /**
   * Given an edible food, add it to its respective stock list.
   *
   * @param edible an edible item
   */
  public void addItemToStock(AbstractEdible edible) {
    if (product instanceof Food) {
      this.foodStock.add(product);
    } else if (product instanceof Drink) {
      this.drinkStock.add(product);
    }
  }
}

这不会产生错误,但是我对类型的松散度感到不满意,我认为可以将其优化。

对于初学者来说,我希望允许我的列表仅只允许允许该特定类型的edible。也就是说,foodStock仅允许添加Food,而drinkStock仅允许添加Drink。我尝试过的是:

private List<AbstractEdible> foodStock = new ArrayList<Food>();
private List<AbstractEdiblet> drinkStock = new ArrayList<Drink>();

在我的IDE中给我一个红色下划线。因此,我更改为:

private List<Food> foodStock = new ArrayList<Food>();
private List<Drink> drinkStock = new ArrayList<Drink>();

这有效,但是我的addItemToStock()方法抱怨我要添加的edible类型为Edible,不能添加到List中包含类型Food。 (这是预期的,因为EdibleFood的父项;即,不是每个Edible都是Food,而是每个FoodEdible

向上/向下强制转换edible也无济于事。然后,我以为Upper Bounded Wildcards是我要的东西,但这也没有用。

除此之外,我也不确定是否使用instanceof是对对象进行分类/排序的最佳方法。

我在这里想念什么?我不了解什么概念?

1 个答案:

答案 0 :(得分:2)

如果您要确保group stage has exceeded the memory limit仅存储foodStock,而Food仅存储drinkStock,则必须像这样初始化列表:

Drink

如果它们来自构造函数,则只需声明它们:

private List<Food> foodStock = new ArrayList<>();
private List<Drink> drinkStock = new ArrayList<>();

,然后在构造函数中分配它们:

private List<Food> foodStock;
private List<Drink> drinkStock;

使用public Store(List<Food> foodStock, List<Drink> drinkStock) { this.foodStock = foodStock; this.drinkStock = drinkStock; } 之后,可以安全地使用强制类型转换:

instanceOf

您还可以创建一个通用的public void addItemToStock(AbstractEdible product) { if (product instanceof Food) { this.foodStock.add((Food) product); } else if (product instanceof Drink) { this.drinkStock.add((Drink) product); } } 类:

Stock

并在您的public class Stock<T extends AbstractEdible> { private List<T> items; public Stock() { items = new ArrayList<>(); } public void addItem(T item) { this.items.add(item); } public List<T> getItems() { return items; } } 中将其用作:

Store