我介绍了一个抽象的actor类,抽象动物类是它的子类。我现在面临的问题是Rabbit类中的act方法(动物的子类)不起作用。
我收到以下错误
“Rabbit不是抽象的,不会覆盖Animal”
中的抽象方法act(java.util.List<Actor>)
我认为狐狸兔的行为方法会覆盖动物和演员中的行为方法。我该如何解决这个问题?
以下是Actor类
中的抽象方法abstract public void act(List<Actor>newActors);
然后使用以下代码
在Animal类中重写此方法abstract public void act(List<Actor> newAnimals);
然后在兔子和狐狸类中使用以下方法覆盖此方法,这是出现错误的地方。
public void act(List<Animal> newRabbits)
{
incrementAge();
if(isAlive()) {
giveBirth(newRabbits);
// Try to move into a free location.
Location newLocation = getField().freeAdjacentLocation(getLocation());
if(newLocation != null) {
setLocation(newLocation);
}
else {
// Overcrowding.
setDead();
}
}
}
答案 0 :(得分:4)
List
的参数化类型是这里的问题,因为它在运行时被删除(参见type erasure),因此污染虚拟方法调用。
您可以在整个类层次结构中使用List<? extends Actor>
对您的方法进行参数化,以解决此问题。
以下内容:
class Actor {
}
class Animal extends Actor {
}
abstract class Abstract {
abstract void act(List<? extends Actor> actors);
}
class Child extends Abstract {
@Override
void act(List<? extends Actor> actors) {
// TODO something
}
}
然后用以下行中的内容调用它:
new Child().act(new ArrayList<Animal>());
答案 1 :(得分:1)
您需要检查方法签名。当签名等于要覆盖的方法的签名时,方法将被覆盖。而act(List<Animal>)
是一个与act(List<Actor>)
不同的签名,因此你没有覆盖它。尝试在@Override
和act
类中的rabbit
方法之前应用fox
,您会发现编译错误(因为它没有覆盖)。
如果您想要覆盖它,只需将方法更改为act(List<Actor>)
和rabbit
类中的fox
。
答案 2 :(得分:0)
如前所述,编译器需要找到与抽象类中具有相同签名的方法。
另一种解决方案是做这样的事情:
abstract class Actor<T extends Actor> {
public abstract void act(List<T> actors);
}
abstract class Animal<T extends Animal> extends Actor<T> {
}
class Rabit extends Animal<Rabit> {
@Override
public void act(List<Rabit> actors) {
// TODO
}
}
这将避免将Girafe作为Rabit类的参数传递:
class Girafe extends Animal<Girafe> {
...
}
new Rabit().act(new ArrayList<Rabbit>()); // It's OK
new Rabit().act(new ArrayList<Girafe>()); // won't compile