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

问题描述 投票:0回答:1

我试图理解多态性,以及通过子类和超类继承工作时的最佳实践。我有三个课程:项目,书籍和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>;

这不会破坏多态性的观点吗?此外,假设我现在想要打印所有项目的列表,我必须调用两个数组列表而不是只保存所有项目列表。

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

java inheritance polymorphism subclass superclass
1个回答
0
投票

如果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做了特定的动作,所以你想要实现的功能不是多态的。

最后一个解决方案,如果你真的想在这里使用多态,那就是在getRuntime()上声明Item并在Book中编写一个实现,它会返回一个什么都不做的Runtime实例。

© www.soinside.com 2019 - 2024. All rights reserved.