Вызов метода подкласса из ArrayList типа суперкласса в Java - PullRequest
0 голосов
/ 24 февраля 2019

Я пытаюсь понять полиморфизм и лучшие практики при работе с наследованием через подклассы и суперклассы.У меня есть три класса: предметы, книги и DVD.Items - это суперкласс, где Books и DVD - это подклассы, расширяющие Items.

Сначала я попытался сохранить новые объекты типа Book и DVD в списке массивов типа Items, который работал нормально.

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

Проблема возникает, когда я пытался вызвать метод getRuntime из подкласса DVD.Это вернет длину пробега DVD.Я не могу переместить этот метод в суперкласс Items, и он не будет применим к книге.

library.get(0).getRuntime();

Я могу понять, почему я получаю ошибку, объект в списке массивов сохраняется типаПредметы, и могут получить доступ только к методам в классе Предметов.Таким образом, один из вариантов - приведение к нужному типу подкласса:

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

Но что, если я вызываю много методов из подкласса, придется ли мне приводить каждый раз?Кроме того, использование литья, как это считается плохой практикой?

Мой другой вариант - создать два отдельных списка массивов для каждого подкласса:

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

Хотя это не разрушает точку полиморфизма?Кроме того, скажем, что теперь я хочу напечатать список всех своих элементов, мне придется вызывать оба списка массивов, а не только тот, который содержит их все.

Спасибо за любую помощь, я могу предоставить более подробный кодпримеры при необходимости.

1 Ответ

0 голосов
/ 24 февраля 2019

Если 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 который ничего не делает.

...