假设我有一个存储泛型类型的集合,例如
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;
施展是唯一能让这项工作的方法吗?我是以错误的方式解决这个问题吗?
由于
答案 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();
}
希望这有帮助。