在Java

时间:2019-02-24 15:20:09

标签: java inheritance polymorphism subclass superclass

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

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

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

1 个答案:

答案 0 :(得分:0)

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

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

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 上声明getRuntime()并在Book中编写一个实现,该实现的确会返回Item的实例,什么都没有。