Вызов метода из класса из элемента в списке объектов

#java #arraylist #types

#java #arraylist #типы

Вопрос:

Предыстория:

У меня есть два класса Book and Video и Driver класс, созданный для хранения списка объектов Book и Video , чтобы иметь виртуальную библиотеку. У каждого класса есть метод, getTitle() который возвращает заданный заголовок из первого параметра конструктора класса как String . Кроме того, у Driver класса есть метод getList() , который возвращает список ( lib в данном контексте) в виде List<Object>

Соответствующие фрагменты:

 List<Object> lib = new ArrayList<Object>();

// Params for each constructor is a single string for the title for this example
Book b = new Book("Book");
Video v = new Video("Video");
lib.add(b);
lib.add(v);
  

Итак, допустим, я запускаю что-то вроде:

 for (int x = 0; x < lib.size(); x  ) {
    System.out.println(getList().get(x).getClass());
}
  

Программа вернет

 class Book
class Video
  

Однако, если я вызываю метод из класса Book или Video (то же имя метода):

 for (int x = 0; x < lib.size(); x  ) {
    System.out.println(getList().get(x).getTitle());
}
  

Я получаю следующую ошибку:

 java: cannot find symbol
  symbol:   method getTitle()
  location: class java.lang.Object
  

Итак, мой вопрос в конечном итоге,

Как я могу вызвать getTitle() из элемента в списке объектов, если getTitle() метода нет в классе Object? Если я переопределяю toString() внутри класса Book или Video , он запускает toString() из Book или Video , как и должно быть — но кажется, что способ его запуска зависит от того, являются ли элементы моего списка Object или экземпляром одного из моих классов.

Решения, о которых я думал, но не знаю, как реализовать:

Приведение элементов обратно к Book или Video . Вызов: Как переменно приводить к нескольким типам и как сделать это встроенным.

Использование другого контейнера, похожего на массив / список, который позволял бы сохранять определенные типы данных Book и Video . Задача: Незнание, возможное чрезмерное усложнение, и я хотел бы иметь возможность использовать списки.

Заключительные замечания

Если вам интересно — Да, это назначение для класса. Вот почему мне нужен ОДИН список / массив вместо двух для каждого типа, что значительно облегчило бы мою жизнь. Причина, по которой я не загрузил весь свой код, заключается в попытке максимально упростить вопрос, учитывая, что у меня есть три уникальных класса, которые я создал, и их гораздо больше, чем Title и один метод для каждого класса. Если это уместно, я мог бы загрузить сам код.

Спасибо, что нашли время в своем дне, чтобы подумать со мной и решить это.

Комментарии:

1. Можете ли вы изменить классы Book и Video или вы не можете из-за назначения?

2. Я сам создал классы, да, я могу их изменить

Ответ №1:

Вам не нужен список объектов здесь; ваша библиотека предназначена для хранения вещей, похожих на библиотеки. Файл не предназначен для хранения здесь. Также не является блокировкой, входным потоком, целым числом, строкой, автомобилем, домом или галактикой.

Определите концепцию того, что может храниться в библиотеке. Сделайте это интерфейсом:

 public interface LibraryWork {
    String getTitle();
}
  

Здесь говорится: существует такая вещь, как понятие «библиотечная работа», и все библиотечные работы имеют то общее, что у них есть названия.

Затем:

 class Book implements LibraryWork {
    ...
}
  

Теперь вы можете создать в своей библиотеке список не объектов, который совершенно бесполезен и чрезмерно широк, а instad List<LibraryWork> .

И теперь вы можете вызывать getTitle для него столько, сколько захотите.

Как правило, избегайте .getClass, instanceof, приведения классов и т. Д. — Если необходимо, создайте список видов библиотечных работ и попросите свой класс Book вернуть ‘BOOK’, если необходимо.

ПРИМЕЧАНИЕ: Мне не слишком нравится название LibraryWork, возможно, вы можете придумать что-нибудь получше.

Комментарии:

1. Если единственное, что есть в интерфейсе, это String getTitle() , то я перенял соглашение из некоторых проектов Google HasTitle .

2. @chrylis-осторожно оптимистично — это нарушает самые разумные соглашения об именовании, которые я когда-либо читал. ‘HasTitle’ на самом деле мало что описывает. В данном случае это намного глубже, чем просто «все, что имеет название» (могу ли я хранить живого человека в библиотеке? Я так не думаю). «Работа» действительно охватывает это понятие, за исключением того, что «work», к сожалению, в английском языке довольно обременен множеством неудачных омонимов.

3. > единственная вещь в интерфейсе

4. Это не имеет значения. Вы ставите телегу впереди лошади. Если мы будем придерживаться вашей логики, то должен быть только один интерфейс маркера, и он должен называться ‘MarkerInterface’. На самом деле у нас их тонна. Сначала вы рассматриваете, что это за вещь, затем вы описываете методы, которые у нее есть (которые могут быть разочаровывающе маленьким списком). То, что вы описываете, — это способ заставить java действовать как дерьмовый структурно типизированный язык.

5. Это идеальное решение моей проблемы. К сожалению, мой профессор будет принимать только массивы / списки, а переопределение toString(), которое действительно работает, — это все, что он хотел. Однако для собственного удовольствия и обучения я решил создать дубликат, в котором реализовано это решение. Большое тебе спасибо, мой друг.