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