2016-01-13 107 views
0

我介绍了抽象动物类是其子类的抽象actor类。我现在面临的问题是,兔类动作方法(动物的一个子类)不起作用。使用泛型参数覆盖方法

我收到以下错误

“兔子不是抽象的,在动物不重写抽象方法act(java.util.List<Actor>)

我认为,在兔子的行为方法狐狸会覆盖在动物的行为方法和演员。我如何解决这个问题?

下面是在Actor类的抽象方法

abstract public void act(List<Actor>newActors); 

该方法然后在动物类与以下代码

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

回答

1

您需要检查方法签名。当签名等于它想要覆盖的方法的签名时,方法会被覆盖。而act(List<Animal>)是另一个签名,然后act(List<Actor>),因此你没有重写它。尝试@Override之前在rabbitfox类的act方法应用,你会发现一个编译器错误(因为it's未覆盖)。

如果您想覆盖它,只需在您的rabbitfox类中将方法更改为act(List<Actor>)即可。

+0

完美的作品,|弄糊涂了,因为我认为Animal类叫Actor类,而rabbit和fox类叫动物类,再次感谢! @Kevin – user5647516

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

正如前面所说的,compilator需要找到具有相同签名梅索德作为抽象类。

另一种解决方案是做这样的事情:

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