繁体   English   中英

从Java中的超类类型的ArrayList调用子类方法

[英]Calling a subclass method from an ArrayList of type superclass in Java

我试图了解多态性,以及通过子类和超类进行继承时的最佳实践。 我有三节课:项目,书籍和DVD。 Items是超类,Books和DVD是扩展Items的子类。

首先,我尝试将Book和DVD类型的新对象存储在Items类型的数组列表中,效果很好。

ArrayList<Items> library = new ArrayList<Items>;
library.add(new DVD(...));
library.add(new Book(...));

当我尝试从DVD子类调用方法getRuntime时出现问题。 这将返回DVD的运行长度。 我无法将此方法移至Items超类,因此不适用于书籍。

library.get(0).getRuntime();

我能理解为什么会出错,数组列表中的对象存储为Items类型,并且只能访问Items类中的方法。 因此,一种选择是强制转换为正确的子类类型:

((DVD) library.get(0)).getRuntime();

但是,如果我要从子类中调用许多方法,我每次都必须强制转换吗? 另外,使用这种转换是否被视为不良做法?

我的另一个选择是为每个子类创建两个单独的数组列表:

ArrayList<DVD> libraryDvds = new ArrayList<DVD>;
ArrayList<Books> libraryBooks = new ArrayList<Books>;

这是否不会击败多态性的观点? 此外,假设我现在想打印所有项目的列表,则必须调用两个数组列表,而不是仅包含所有数组的列表。

感谢您的帮助,如有需要,我可以提供更详细的代码示例。

如果getRuntime确实是DVD特有的,则getRuntime是唯一的方法。 您将需要在每次需要的时候进行投射。 强制转换之前,好的做法是(使用instanceof)检查类型,或者捕获ClassCastException

但是,更优雅的方法可能是拥有DVD列表而不是项目列表。 如果需要,您还可以列出项目清单。

ArrayList<Items> library = new ArrayList<Items>; // list to use when processing the whole library
ArrayList<DVD> libraryDvds = new ArrayList<DVD>; // list to use when processing only DVDs

我不认为您这样做会克服多态性的问题,因为您仅对DVD执行特定的操作,因此要实现的功能不是多态的。

最后一种解决方案,如果您真的想在这里使用多态性,那就是在Item上声明getRuntime()并在Book中编写一个实现,该实现将返回不执行任何操作的Runtime实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM