Тип передачи Java в качестве параметра в функцию, ожидающую подтипа

Я новичок в Java, и я пытаюсь сделать некоторые действительно простые приложения Java. В моих попытках я столкнулся с проблемой обобщения. У меня есть список объектов Person. Человек может быть отцом или матерью.

Затем у меня есть несколько методов с тем же именем есть (...), но они отличаются по входным параметрам. Эти методы не являются частью класса Person. Один из этих методов принимает Мать в качестве параметра, а другой принимает Отца.

Вопрос в том, как динамически решить, какой метод вызывать из списка Person. когда я пытаюсь выполнить итерацию по списку и вызвать o.eat (iterator), он выдает ошибку компилятора, потому что итератор имеет тип Person, но мои методы eat хотят использовать в качестве параметров Mother или Father. Компилятор не знает, что у меня есть метод для каждого типа человека

До сих пор я решил свою проблему с помощью оператора if, в котором я сравниваю тип класса методом GetType() как с матерью, так и с отцом, и, если он равен, я могу преобразовать Person в соответствующий тип.

Код выглядит так:

  if (person.getClass().equals(Father.class)) {
            theView.eat((Father) person);
        }


  if (person.getClass().equals(Mother.class)) {
            theView.eat((Mother) person);
        }

Метод приема выглядит следующим образом:

 public void eat(Mother m){
    textArea.append(m.breakfast);
    textArea.append(m.lunch);
    textArea.append(m.dinner);
 }

обед, ужин и завтрак - это просто строка, указывающая, что делает человек

person - это код итератора в списке объектов Person

Есть ли лучшее решение, которое автоматизирует процесс?

Спасибо заранее.

3 ответа

Решение

Затем у меня есть несколько методов с тем же именем есть (...), но они отличаются по входным параметрам

Что делать, если ваш класс с разными eat Методы реализованы следующим образом:

public class TheView<T extends Person> {
    public void eat(T t) {
         textArea.append(t.getMeals());
    }
}

И теперь ваш итерационный метод может быть реализован следующим образом:

public <T> void yourMethod(List<? extends Person> personList) {
    for (Person p : personList) {
         theView.eat(p);
    }
}

Ваш список может содержать любое количество Father или же Mother объекты при условии, что они реализуют / расширяют Person класс, как

public abstract class Person {
    private String breakfast;
    private String lunch;
    // ... other fields

    public abstract void getMeals();

    public String getBreakfast() { return breakfast; }
    // ... other getters
}

public class Father extends Person {
     @Override
     public void getMeals() {
         // implement Father-specific code here
     }
}

public class Mother extends Person {

     @Override
     public String getMeals() {
        StrngBuilder sb = new StringBuilder() ;

        sb.append(getBreakfast());
        sb.append(getLunch());
        sb.append(getDinner());

        return sb.toString();
    }
}

Используйте полиморфизм:

public interface Person{
    void eat();
}

public class Mother implements Person{

    @Override
    public void eat()
    {
        //the code inside eat(Mother) goes here
    }

}

public class Father implements Person{

    @Override
    public void eat()
    {
        //the code inside eat(Father) goes here
    }

}

затем просто вызовите метод eat для каждого объекта в списке вашего персонажа:

for(final Person person: personList){
    person.eat();
}

Я думаю, что вам нужен шаблон посетителя, из-за того, что вы сказали здесь

Вопрос в том, как динамически решить, какой метод вызывать из списка Person.

https://sourcemaking.com/design_patterns/visitor/java/2

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

Из Википедии: https://en.wikipedia.org/wiki/Double_dispatch

двойная диспетчеризация - это особая форма множественной диспетчеризации и механизм, который отправляет вызов функции различным конкретным функциям в зависимости от типов времени выполнения двух объектов, участвующих в вызове.

Другие вопросы по тегам