简体   繁体   中英

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. Items is the superclass, where Books and DVDs are the subclasses that extend Items.

At first, I tried storing new objects of type Book and DVD in an array list of type Items, which worked fine.

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. This would return the run length of the DVD. I can't move this method to the Items superclass and it would not be applicable to a book.

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. 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. You will need to cast each time needed. Before casting, good practice would be to check type before (using instanceof), or catch ClassCastException .

But a more elegant way could be to have a list of DVD instead of a list of Items. 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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