无法在初始化为超类的 ArrayList 中调用派生类的方法
Posted
技术标签:
【中文标题】无法在初始化为超类的 ArrayList 中调用派生类的方法【英文标题】:Unable to call derived class's method in ArrayList initialized to super class 【发布时间】:2019-05-21 15:10:24 【问题描述】:我正在通过 Java 学习面向对象的编程,并正在编写一个冰箱程序来练习。在我的程序中,有两个派生类 PerishableItem 和 LeftoverItem 的类 Item。我创建了一个初始化为 Item 的 ArrayList,并向 ArrayList 添加了一个 PerishableItem 和一个 LeftoverItem。问题是我无法调用派生类中不在 Item 类中的方法。
ArrayList<Item> itms = new ArrayList<Item>();
itms.add(new Item("apple", 0.45, new Date(1, 1, 2001)));
itms.add(new LeftoverItem("rice", 9.99, new Date(1, 1, 2001), 3));
itms.add(new PerishableItem("yogurt", 4.48, new Date(1, 1, 2001), 5));
System.out.println(itms.get(2).getDaysToExpire()); // error here
getDaysToExpire() 是 PerishableItem 类中的方法,而不是 Item 类中的方法。似乎编译器甚至根本看不到该方法。谢谢!
【问题讨论】:
方法是private
吗?
itms.get(2)
将返回一个Item
类型的对象(因为该列表被声明为ArrayList<Item>
)。如果getDaysToExpire()
不是Item
上的方法,那么这就是编译器使其失败的原因。
您可以在 Item 类中使用 getDaysToExpire() 方法。如果您有特定于子类的内容,则可以在派生类 LeftoverItem、PerishableItem 中覆盖 getDaysToExpire() 方法。
【参考方案1】:
Item
还应该有 getDaysToExpire
() 方法才能工作...但是当您调用它们时,派生类中的正确 getDaysToExpire
() 将被调度。
另一种方法是将items.get(2)
类型转换为PerishableItem
,然后调用getDaysToExpire
,但这绝对不是一个好的设计。
冰箱里的任何物品都会有一个有效期,所以,我不明白为什么 Item 类中也没有这个方法。
【讨论】:
出于好奇,为什么将 items.get() 类型转换为 PerishableItem 不好?感谢您的建议! @JustinLam 在很多中,让我们举一个简单的情况.. 如果您进行类型转换,那么除了 PerishableItem 之外,您不能在 items[2] 中放置任何其他对象。另外,假设您从冰箱中删除了“米饭”,那么 Yogurt 将成为 items(1)...您可以使用反射来解决此问题,但正确的解决方案是简洁且定义明确的继承。以上是关于无法在初始化为超类的 ArrayList 中调用派生类的方法的主要内容,如果未能解决你的问题,请参考以下文章
Swift:“必须调用超类的指定初始化程序”错误,即使代码正在这样做