在 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=] 什么都不做。
我正在尝试了解多态性,以及通过子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=] 什么都不做。