简体   繁体   English

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

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

I am trying to understand polymorphism, and the best practice when working with inheritance through subclasses and superclasses. 我试图了解多态性,以及通过子类和超类进行继承时的最佳实践。 I have three classes: Items, Books, and DVDs. 我有三节课:项目,书籍和DVD。 Items is the superclass, where Books and DVDs are the subclasses that extend Items. Items是超类,Books和DVD是扩展Items的子类。

At first, I tried storing new objects of type Book and DVD in an array list of type Items, which worked fine. 首先,我尝试将Book和DVD类型的新对象存储在Items类型的数组列表中,效果很好。

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

The problem occurrs when I tried calling a method getRuntime from the DVD subclass. 当我尝试从DVD子类调用方法getRuntime时出现问题。 This would return the run length of the DVD. 这将返回DVD的运行长度。 I can't move this method to the Items superclass and it would not be applicable to a book. 我无法将此方法移至Items超类,因此不适用于书籍。

library.get(0).getRuntime();

I can understand why I get an error, the object in the array list is stored of the type Items, and can only access the methods in the Items class. 我能理解为什么会出错,数组列表中的对象存储为Items类型,并且只能访问Items类中的方法。 So one option is to cast to the right subclass type: 因此,一种选择是强制转换为正确的子类类型:

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

But what if I am calling many methods from the subclass, would I have to cast each time? 但是,如果我要从子类中调用许多方法,我每次都必须强制转换吗? Also, is using cast like this considered bad practice? 另外,使用这种转换是否被视为不良做法?

My other option would be to create two seperate array lists for each subclass: 我的另一个选择是为每个子类创建两个单独的数组列表:

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

Does this not defeat the point of polymorphism though? 这是否不会击败多态性的观点? Furthermore, say I now wanted to print a list of all my items, I'd have to call both array lists rather than just one that holds them all. 此外,假设我现在想打印所有项目的列表,则必须调用两个数组列表,而不是仅包含所有数组的列表。

Thanks for any help, I can provide more detailed code examples if needed. 感谢您的帮助,如有需要,我可以提供更详细的代码示例。

If getRuntime is really specific to DVD then the cast is the only way to go. 如果getRuntime确实是DVD特有的,则getRuntime是唯一的方法。 You will need to cast each time needed. 您将需要在每次需要的时候进行投射。 Before casting, good practice would be to check type before (using instanceof), or catch ClassCastException . 强制转换之前,好的做法是(使用instanceof)检查类型,或者捕获ClassCastException

But a more elegant way could be to have a list of DVD instead of a list of Items. 但是,更优雅的方法可能是拥有DVD列表而不是项目列表。 You could also have a list of items if you need it. 如果需要,您还可以列出项目清单。

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

I don't think you are defeating the point of polymorphism by doing this because you are doing specific actions only for DVD, so the function you want to implement is not polymorphic. 我不认为您这样做会克服多态性的问题,因为您仅对DVD执行特定的操作,因此要实现的功能不是多态的。

A last solution, if you really want to use polymporphism here would be to declare getRuntime() on Item and write an implementation in Book that would do return an instance of Runtime which does nothing. 最后一种解决方案,如果您真的想在这里使用多态性,那就是在Item上声明getRuntime()并在Book中编写一个实现,该实现将返回不执行任何操作的Runtime实例。

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

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