Java继承:如何根据并非所有项都拥有的属性从ArrayList中删除项?
我想知道如何编辑我的代码,这样我就可以删除cleanShelf方法中的项目,这不仅取决于项目是否已按日期通过使用,还取决于它们是否已打开。问题是dateOpened属性只属于DiaryFood类型的项目,我不知道如何在我的Shelf类中访问它 食物: 日记食品:Java继承:如何根据并非所有项都拥有的属性从ArrayList中删除项?,java,inheritance,polymorphism,subclass,superclass,Java,Inheritance,Polymorphism,Subclass,Superclass,我想知道如何编辑我的代码,这样我就可以删除cleanShelf方法中的项目,这不仅取决于项目是否已按日期通过使用,还取决于它们是否已打开。问题是dateOpened属性只属于DiaryFood类型的项目,我不知道如何在我的Shelf类中访问它 食物: 日记食品: public class DiaryFood extends Food { private int dateOpened; public DiaryFood(String name, int calorieAmoun
public class DiaryFood extends Food {
private int dateOpened;
public DiaryFood(String name, int calorieAmount, int useDate, int dateOpened) {
super(name, calorieAmount, useDate);
this.dateOpened = dateOpened;
}
public int getdateOpened() {
return dateOpened;
}
}
蔬菜食品:
public class VegFood extends Food {
private String colour;
public VegFood(String name, int calorieAmount, int useDate, String colour) {
super(name, calorieAmount, useDate);
this.colour = colour;
}
}
货架:
public class Shelf {
ArrayList<Food> food;
public Shelf() {
food = new ArrayList<Food>();
}
public void addFood(Food product) {
this.food.add(product);
}
public void printShelfDetails() {
for (Food f : food)
{
System.out.println(f.getName() + " " + f.getuseDate());
}
}
public void cleanShelf(int day) {
ArrayList<Food> foodToRemove = new ArrayList<Food>();
for (int i = 0; i < food.size(); i++) {
if (food.get(i).getuseDate() < day) {
foodToRemove.add(food.get(i));
}
}
food.removeAll(foodToRemove);
}
}
公共类工具架{
ArrayList食品;
公共货架(){
食品=新ArrayList();
}
公共食品(食品){
本.食品.添加(产品);
}
公共作废打印架详细信息(){
食品(f:食品)
{
System.out.println(f.getName()+“”+f.getuseDate());
}
}
公共货架(国际日){
ArrayList foodToRemove=新建ArrayList();
对于(inti=0;i
如果您想继续操作食品
声明的类型,并且希望避免操作集合中的特定类型,或者对日记食品
进行降级,您可以在食品
类中添加一个返回null
的方法GetDateOpen()
您应该将返回的类型从int
值更改为Integer
值,以便能够返回null
值:
public abstract class Food {
public Integer getdateOpened() {
return null;
}
}
在实际具有dateOpened
字段的具体类中,您可以覆盖它:
@Override
public Integer getdateOpened() {
return dateOpened;
}
当然,在其他没有dateOpened
字段的具体类中,可以保留基类的实现:Food
这样,在循环中,您可以执行以下操作:
for (int i = 0; i < food.size(); i++) {
Foot currentFood = food.get(i);
if (currentFood.getuseDate() < day && currentFood.getDateOpened() != null && yourConditionAboutDateOpened) {
foodToRemove.add(food.get(i));
}
}
for(inti=0;i
DiaryFood
的instance
,并进行适当的日期打开检查cleanself
方法不是很有效。使用iterator
或removeIf
从列表中删除元素是更好、更干净的选择food.removeIf(item -> item.getuseDate() < day
|| (item instanceof DiaryFood && ((DiaryFood) item).dateOpened < day));
food.removeIf(item->item.getuseDate()
或
Iterator Iterator=food.Iterator();
while(iterator.hasNext()){
Food item=iterator.next();
如果(item.getuseDate()<天
||(日粮项目实例)
&&((日记食品)项目)。开放日期<天){
iterator.remove();
}
}
使用instanceof
和casting可能在几个类中看起来很简单,但是想象一下,如果您有10个子类Food
,每个子类都有自己的删除逻辑
将方法getDateOpened()
添加到Food
类中,使其在没有dateOpened
属性的类中返回null
,会给接口增加不必要的复杂性。用户必须知道,对于某些Food
子类,此方法将返回有效值,而对于其他子类,则不会返回有效值。它也不能很好地扩展子类的数量
一个类型安全的选择是将决定某种类型的食物应该被移除的逻辑移到该类型本身
例如,在Food
类中创建方法shouldBeRemoved(int)
:
public abstract class Food {
public boolean shouldBeRemoved(int day) {
return this.useDate < day;
}
}
因此,在Shelf
类中,您可以执行以下操作:
public void cleanShelf(int day) {
ArrayList<Food> foodToRemove = new ArrayList<Food>();
for (int i = 0; i < food.size(); i++) {
if (food.get(i).shouldBeRemoved(day)) {
foodToRemove.add(food.get(i));
}
}
food.removeAll(foodToRemove);
}
我不建议这种方法。它在某种程度上增加了公共api的开销。为什么不建议改用
接口
呢?不管是否使用接口,如果不想强制转换,您必须更改api。这一切都取决于用户想要什么:执行强制转换或打开合同。这就是为什么我在回答中对它进行了细化。@Adowrath没问题:)两件事:DiaryFood不能使用this.useDate
,因为它在父类中是私有的。而且,我想你应该提到,在某种程度上,这让事情变得复杂,因为现在不是货架决定“嘿,我不再想要这种食物了!”,而是食物说“嘿,我不再适合了!”。根据你正在从事的项目,这可能根本不是一个问题,也可能是一个非常非常大的问题。
public abstract class Food {
public boolean shouldBeRemoved(int day) {
return this.useDate < day;
}
}
public class DiaryFood extends Food {
@Override
public boolean shouldBeRemoved(int day) {
return this.getUseDate() < day || this.dateOpened < day;
}
}
public void cleanShelf(int day) {
ArrayList<Food> foodToRemove = new ArrayList<Food>();
for (int i = 0; i < food.size(); i++) {
if (food.get(i).shouldBeRemoved(day)) {
foodToRemove.add(food.get(i));
}
}
food.removeAll(foodToRemove);
}
public void cleanShelf(int day) {
food.removeIf(food -> food.shouldBeRemoved(day));
}