#java #class #inheritance
#java #класс #наследование
Вопрос:
Я пытаюсь перебрать несколько объектов разных типов, которые все расширяют один и тот же родительский класс. Например:
ArrayList<Enchant> enchants = new ArrayList<>();
Внутри массива enchants будут объекты классов, которые расширяют Enchant
класс.
Например:
public class JumpBoost extends Enchant{
public static Item generateItem(){
return something;
}
}
У каждого объекта в зачаровывающем ArrayList будет метод с именем generateItem() .
Я хотел бы пройти через него, используя:
for(Enchant enchant : enchants){
enchant.generateItem()
}
Я уже пытался это сделать, но безуспешно из-за того, что класс Enchant не имеет generateItem()
метода.
По сути, мне просто нужен способ группировать и перебирать несколько объектов разных типов.
Ответ №1:
Идиоматический подход заключается в определении абстрактного generateItem()
на Enchant
. Если вы Enchant
по какой-то причине не можете изменить, вы можете создать абстрактный подкласс of Enchant
и сделать так, чтобы все ваши подклассы наследовали от него.
Вы также можете попробовать создать интерфейс, с generateItem()
помощью которого все подклассы реализуют и сохраняют тип интерфейса в ArrayList
.
Если вы по-прежнему не можете выполнить ни одно из этих действий по какой-либо причине, вам следует пересмотреть свой дизайн. Но в качестве последнего средства вы можете использовать отражение для динамического доступа к generateItem
каждому отдельному подклассу. Просто вызовите .getClass()
, а затем найдите метод и вызовите его.
Ответ №2:
Вы можете использовать полиморфизм для решения этой проблемы.
Сначала определите базовый класс / абстрактный класс / интерфейс с помощью метода generateItem(), производите указанные классы и переопределяйте / реализуйте метод generateItem() .
Вот реализация с интерфейсом:
interface Base{
void generateItem();
}
class Derived1 implements Base{
@Override
public void generateItem() {
System.out.println("generateItem() from Derived1");
}
}
class Derived2 implements Base{
@Override
public void generateItem() {
System.out.println("generateItem() from Derived2");
}
}
class Main {
public static void main(String[] args) {
List<Base> list = new ArrayList<>();
list.add(new Derived1());
list.add(new Derived2());
list.forEach(Base::generateItem);
}
}
Вывод:
generateItem() from Derived1
generateItem() from Derived2
Подробнее о полиморфизме вы можете прочитать здесь .
Комментарии:
1. Разве второй вывод не должен быть из Derived2?
Ответ №3:
Укажите Enchant
абстрактный метод, который необходимо реализовать подклассам. Для того, чтобы сделать его абстрактным, Enchant
не требуется определение метода, но для подклассов требуется.
public class Enchant {
public abstract Item generateItem();
}
Метод не должен быть static
методом, как у вас есть в вашем коде. Это должен быть метод экземпляра, поскольку вы вызываете его в экземплярах Enchant
.
Ответ №4:
Создайте enchant как интерфейс или абстрактный класс и расширьте его в производных классах