2016-01-13 105 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