2013-06-01 61 views
1

假设我有一个存储泛型类型的集合,例如Java方法返回类型专精

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()); 

我想调用特定于每个子类型的方法。例如

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; 

是铸造唯一的方式来做这项工作?我是否以这种错误的方式去做?

谢谢

回答

0

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

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

0

编译器只能理解引用类型。因此,当你编写Human时,编译器会尝试在Human类中寻找它不能找到的方法,因为它实际上是实现了Human的其他方法,而试图调用的方法不在Human本身。

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

例如,

Human h=new Killer(); 

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

希望这会有所帮助。

1

如果你想要一个人能够做这两个动作,你需要在Human中声明这个。

一个更简单的方法是有一个通用的act方法,导致一个人很好,谋杀杀人。这样呼叫者不需要知道人类会采取什么行动。