2

我是 Java 新手,我尝试制作一些非常简单的 Java 应用程序。在我的尝试中,我遇到了泛化问题。我有一个Person对象列表。可以是父亲母亲

然后,我有几个同名的方法eat(...)但它们的输入参数不同。这些方法不是Person类的一部分。其中一种方法接受Mother作为参数,另一种接受Father

问题是如何动态决定在Person列表上调用哪个方法。当我尝试遍历列表并调用o.eat(iterator)时,它会提示编译器错误,因为迭代器是Person类型,但我的eat方法需要母亲父亲作为参数。编译器不知道我对每种类型的人都有方法

到目前为止,我已经用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 对象列表的迭代器

有没有更好的解决方案可以使过程自动化?

提前谢谢。

4

3 回答 3

1

然后,我有几个同名的方法 eat(...) 但它们的输入参数不同

如果您的具有不同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();
    }
}
于 2016-04-29T16:50:03.497 回答
1

使用多态性:

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
    }

}

然后,只需在您的 Person 列表的每个对象上调用 eat 方法:

for(final Person person: personList){
    person.eat();
}
于 2016-04-29T14:32:31.100 回答
0

我认为您需要访问者模式,因为您在这里所说的

问题是如何动态决定在 Person 列表上调用哪个方法。

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

这有助于您决定在运行时动态采用哪条路由

来自维基百科:https ://en.wikipedia.org/wiki/Double_dispatch

双重分派是多重分派的一种特殊形式,是一种根据调用所涉及的两个对象的运行时类型将函数调用分派到不同的具体函数的机制。

于 2016-04-29T15:49:07.440 回答