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

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

我正在尝试了解多态性,以及通过子classes 和 superclasses 处理继承时的最佳实践。我有三个 classes:物品、书籍和 DVD。 Items 是超class,其中 Books 和 DVD 是扩展 Items 的子class。

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

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

当我尝试从 DVD subclass 调用方法 getRuntime 时出现问题。这将 return DVD 的 运行 长度。我无法将此方法移动到 Items superclass 并且它不适用于一本书。

library.get(0).getRuntime();

我能理解为什么报错了,数组列表中的对象存储的是Items类型,只能访问Items中的方法class。因此,一种选择是向右转换 subclass type:

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

但是如果我从 subclass 调用许多方法,我是否必须每次都强制转换?另外,像这样使用 cast 是否被认为是不好的做法?

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

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

但这不是破坏了多态性的意义吗?此外,假设我现在想打印我所有项目的列表,我必须调用两个数组列表,而不是只调用一个包含所有项目的列表。

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

如果 getRuntime 确实特定于 DVD,那么演员表是唯一的出路。您需要在每次需要时进行投射。 在投射之前,好的做法是先检查类型(使用 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 中编写一个实现 return [的实例=15=] 什么都不做。