Java方法返回类型专业化

时间:2013-06-01 11:25:32

标签: java polymorphism

假设我有一个存储泛型类型的集合,例如

public class MyCollection<T> {
    public T getNext()
    {
        //Remove T from list
        //Return T
    }
}

我正在使用此集合来存储子类型,例如

public class NormalPerson extends Human {
    public void beNice() { }
}
public class Murderer extends Human {
    public void kill() { }
}

...

MyCollection<Human> people = new MyCollection<>();

people.add(new NormalPerson());
people.add(new Murderer());

我想调用特定于每个子类型的方法。 e.g。

Human person = people.getNext();
switch(person.getType()) {
    case NORMAL:
        person.beNice(); //Symbol not found
        break;
    case MURDERER:
        person.kill(); //Symbol not found
        break;
}

但除非我演员,否则我不能,例如

switch(people.getNext().getType()) {
    case NORMAL:
        NormalPerson person = (NormalPerson)people.getNext();
        person.beNice();
        break;

施展是唯一能让这项工作的方法吗?我是以错误的方式解决这个问题吗?

由于

3 个答案:

答案 0 :(得分:1)

如果您希望Human能够执行这两项操作,则需要在Human中声明此内容。

一种更简单的方法是使用通用act方法,使一个人变得善良,一个谋杀者可以杀死。这样调用者就不需要知道人类会采取什么行动。

答案 1 :(得分:0)

你是以错误的方式去做的。调用代码不应该检查甚至关心对象的确切类型,应该足以知道它是Human的类型。

解决此问题的常用方法是为方法设置一个更通用的名称,可能是Human#doAction(),并让每个扩展Human的类通过重写该方法来定义其专用行为。这样,无论您拥有哪个Human,都可以调用相同的方法,这极大地简化了代码。

答案 2 :(得分:0)

编译器只能理解引用类型。因此,当您编写Human时,编译器将尝试在Human类中查找它无法找到的方法,因为它实际上是实现Human的其他方法,并且尝试调用的方法不在Human中本身。

你可以做的是你可以使用instanceof运算符来检查它实际上是什么类型的对象,否则转换是唯一的方法。

例如

Human h=new Killer();

if(h instanceof Killer)
{
    (Killer)h.kill();
}

希望这有帮助。