[英]How to use subtype polymorphism & generics for lists?
I'm learning Java, and have read about inheritance and subtype polymorphism. 我正在学习Java,并已阅读有关继承和子类型多态性的知识。 Now I'm just starting to learn about generics, and I'm trying to put the pieces together, but am stuck.
现在,我才刚刚开始学习泛型,并且试图将各个部分放在一起,但被卡住了。
Say I've an abstract
parent class AbstractEdibles
, and there are two children that extend
from it: Food
and Drink
. 说我一个
abstract
父类AbstractEdibles
,并有两个孩子是extend
从它: Food
和Drink
。 Also, I've a Store
that has two List
s: one to store Food
and one to store Drink
. 另外,我的
Store
有两个List
:一个用于存储Food
,另一个用于存储Drink
。
Now, I want my Store
to be able to have behaviors, such as adding to its stock. 现在,我希望我的
Store
能够有某种行为,例如增加库存。 My desired approach is to define one method to take in a product and put it in the appropriate list. 我想要的方法是定义一种方法来接收产品并将其放入适当的列表中。 If it's a
Food
type, put it in the food list. 如果是
Food
类型,请将其放入食物清单。 If it's of type Drink
, put it in the drink list. 如果是
Drink
类型,则将其放入饮料列表中。
I'm sure I need to use generics and subtype polymorphism. 我确定我需要使用泛型和子类型多态性。 Here's a snippet of my code:
这是我的代码片段:
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);
}
}
}
This doesn't give errors, but I'm unhappy with how loose I'm being with the types, and I think it could be made more optimal. 这不会产生错误,但是我对类型的松散度感到不满意,我认为可以将其优化。
For starters, I'd prefer to allow my list to only allow that specific type of edible
. 首先,我希望允许我的清单仅允许该特定类型的
edible
。 That is, foodStock
will only allow Food
to be added, and drinkStock
will only allow Drink
to be added. 也就是说,
foodStock
仅允许添加Food
,而drinkStock
仅允许添加Drink
。 What I tried was: 我试过的是:
private List<AbstractEdible> foodStock = new ArrayList<Food>();
private List<AbstractEdiblet> drinkStock = new ArrayList<Drink>();
gives me a red underline in my IDE. 在我的IDE中给我一个红色下划线。 So then I changed to:
因此,我更改为:
private List<Food> foodStock = new ArrayList<Food>();
private List<Drink> drinkStock = new ArrayList<Drink>();
this works, but then my addItemToStock()
method complains that the edible
I'm trying to add is of type Edible
and can't be added to a List
containing type Food
. 这工作,但后来我
addItemToStock()
方法抱怨说, edible
我想补充的是类型的Edible
,不能被添加到List
包含类型Food
。 (This is expected, because Edible
is the parent of Food
; ie not every Edible
is a Food
, but every Food
is Edible
.) (这是预料之中的,因为
Edible
是Food
的父项;即,并非每种Edible
都是Food
,但是每种Food
都是Edible
。)
Up/Down casting edible
doesn't help, either. 上下浇铸
edible
也无济于事。 I then thought Upper Bounded Wildcards was what I was looking for, but that also didn't work. 然后我以为我想要的是上界通配符 ,但这也没有用。
Besides that, I'm also unsure if using instanceof
is the best way to classify/sort objects. 除此之外,我也不确定使用
instanceof
是否是对对象进行分类/排序的最佳方法。
What am I missing here? 我在这里想念什么? What concept am I not understanding?
我不了解什么概念?
If you want to ensure that foodStock
stores Food
only and drinkStock
stores Drink
only, then you'll have to initialize your lists like this: 如果你想确保
foodStock
店Food
只和drinkStock
店Drink
而已,那么你就必须初始化列表如下:
private List<Food> foodStock = new ArrayList<>();
private List<Drink> drinkStock = new ArrayList<>();
If they are coming from constructor, just declare them: 如果它们来自构造函数,则只需声明它们:
private List<Food> foodStock;
private List<Drink> drinkStock;
and then assign them in constructor: 然后在构造函数中分配它们:
public Store(List<Food> foodStock, List<Drink> drinkStock) {
this.foodStock = foodStock;
this.drinkStock = drinkStock;
}
And once you have used instanceOf
, it is safe to use casting: 并且一旦您使用
instanceOf
,就可以安全地使用casting:
public void addItemToStock(AbstractEdible product) {
if (product instanceof Food) {
this.foodStock.add((Food) product);
} else if (product instanceof Drink) {
this.drinkStock.add((Drink) product);
}
}
You could also create a generic Stock
class: 您还可以创建一个通用的
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;
}
}
and use it in your Store
as: 并在您的
Store
中将其用作:
public class Store {
private Stock<Food> foodStock;
private Stock<Drink> drinkStock;
public Store() {
this.foodStock = new Stock<>();
this.drinkStock = new Stock<>();
}
public Store(Stock<Food> foodStock, Stock<Drink> drinkStock) {
this.foodStock = foodStock;
this.drinkStock = drinkStock;
}
public void addItemToStock(AbstractEdible product) {
if (product instanceof Food) {
this.foodStock.addItem((Food) product);
} else if (product instanceof Drink) {
this.drinkStock.addItem((Drink) product);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.