与Java泛型和子类化混淆

时间:2013-03-22 04:45:33

标签: java generics wildcard subclassing

我有以下内容:

  • 抽象类BaseScore
  • LevelScore这是BaseScore
  • 的子类

然后我有:

  • 抽象类BaseScoreRecord

    public abstract class BaseScoreRecord<T extends BaseScore> {
         public BaseScoreRecord(){
            init();
         }
    
         protected T[] mScoreHistory;
         protected int count=0;
         protected float finalScore;
    
         protected abstract void calcFinalScore();
         protected abstract void init();
    
         public float getFinalScore() {
             return mFinalScore;
         }
    
         public void addScoreRecord(T score){
             mScoreHistory[count] = score;
             count++;
         }
    }
    
  • ...和MyScoreRecordBaseScoreRecord

    的子类
    public class MyScoreRecord extends BaseScoreRecord<LevelScore> {
         public MyScoreRecord(){
            init();
         }
    
         @Override
         protected void calcFinalScore(){
             //Does some stuff to calc final score from mScoreHistory
         }
    
         @Override
         protected void init(){
             mScoreHistory = new LevelScore[10];
             for (int i=0;i<mScoreHistory.length;i++){
                 mScoreHistory[i] = new LevelScore();
             }
         };
    }
    

那么,我有BaseGame,其中包含以下行:

protected BaseScoreRecord<? extends BaseScore> endGameRecord;

...和MyGameBaseGame的子类。 MyGame包括以下方法:

@Override
protected void gameInit(){
    endGameRecord = new MyScoreRecord();  //endGameRecord initialised
}


protected void addLevelScore(LevelScore ls){
    mEndGameRecord.addScoreRecord(ls);
}

我在最后一个方法上遇到编译器错误:

The method addScoreRecord(capture#3-of ? extends BaseScore) 
in the type BaseScoreRecord <capture#3-of ? extends BaseScore>
is not applicable for the arguments (LevelScore)

...所以我显然在泛型,通配符和子类化方面做错了。如果我在BaseGameMyGame中丢失了泛型,那么它似乎运行时没有任何令人讨厌的ClassCastException错误。任何指针都将非常感激。也许我为自己弄得太复杂了?

1 个答案:

答案 0 :(得分:1)

您应该声明MyScoreRecord实际上是BaseScoreRecord的子类,并正确地对其进行参数化:

public class MyScoreRecord extends BaseScoreRecord<LevelScore>

例如,如果您正在使用Eclipse,则会收到警告,因为@Override注释实际上并未覆盖任何内容。上述内容还将使编译器强制LevelScore扩展BaseScore