2012-01-01 8 views
7

と同等で使用することはできません。は、次のコードを考えると、父と息子、孫の継承

public abstract class Participant { 
    private String fullName; 

    public Participant(String newFullName) { 
     this.fullName = new String(newFullName); 
    } 

    // some more code 
} 


public class Player extends Participant implements Comparable <Player> {  
    private int scoredGoals; 

    public Player(String newFullName, int scored) { 
     super(newFullName); 
     this.scoredGoals = scored; 
    } 

    public int compareTo (Player otherPlayer) { 
     Integer _scoredGoals = new Integer(this.scoredGoals); 
     return _scoredGoals.compareTo(otherPlayer.getPlayerGoals()); 
    } 

    // more irrelevant code 
} 

public class Goalkeeper extends Player implements Comparable <Goalkeeper> { 
    private int missedGoals;   

    public Goalkeeper(String newFullName) { 
     super(newFullName,0); 
     missedGoals = 0; 
    } 

    public int compareTo (Goalkeeper otherGoalkeeper) { 
     Integer _missedGoals = new Integer(this.missedGoals); 
     return _missedGoals.compareTo(otherGoalkeeper.getMissedGoals()); 
    } 

    // more code 
} 

問題はGoalkeeperがcomplieないということです。

私はEclipseがスローそのコードコンパイルしよう:

The interface Comparable cannot be implemented more than once with 
different arguments: Comparable<Player> and Comparable<Goalkeeper> 

私はPlayerと比較しようとしているが、Goalkeeperで、そして彼だけではないんだが。

私は間違っていますか?

+0

、あなたのコード例ではインデントや空白を修正することができますしてください。読むのはとても難しいです。 –

+0

完了、申し訳ありません。今は大丈夫だと思う。 – ron

+0

なぜ 'new String()'がコンストラクタにありますか?文字列は不変です! – fge

答えて

4

あなたのデザインのロジックが間違ったことはしていません。しかし、Javaには、ジェネリック(型消去による)の実装方法に起因する、異なる型パラメータを持つ同じ汎用インタフェースを実装できないという制限があります。

コードでGoalkeeperPlayerの実装をComparable <Player>から継承し、独自のComparable <Goalkeeper>を追加しようとします。これは許可されていません。

この制限に対処する最も簡単な方法は、GoalkeeperComparable <Player>をオーバーライドすることで、Goalkeeperに渡されたプレーヤーをキャストし、thisゴールキーパーと比較します。

編集

public int compareTo (Player otherPlayer) { 
    Goalkeeper otherGoalkeeper = (Goalkeeper)otherPlayer; 
    Integer _missedGoals = new Integer(this.missedGoals); 
    return _missedGoals.compareTo(otherGoalkeeper.getMissedGoals()); 
} 
+0

あなたはこれを行うには意味: "パブリッククラスゴールキーパーはプレイヤーが同等のを実装して拡張する" ... \t公共int型のcompareTo(ゴールキーパーotherGoalkeeper) \t { \t \t整数_missedGoals =新しい整数(this.missedGoals)。 \t \t return _missedGoals.compareTo(otherGoalkeeper.getMissedGoals()); \t} "?? – ron

+2

@ronあなたは' Comparable 'を実装する必要はありません:' Player'を拡張しているのでそこにあります: '@Override public int compareTo(Player otherGoalkeeper){...} '問題だ – dasblinkenlight

+0

:公共int型のcompareTo(ゴールキーパーotherGoalkeeper) \t { \t \t整数_missedGoals =新しい整数(this.missedGoals:プレイヤーはフィールドmissedGoalsを持っていない、とクラスGoalkepperが、私はこれをしなかったし、そのクラスに気づくしてください、 ); \t \t返信_missedGoals.compareTo(otherGoalkeeper.getMissedGoals()); \t} – ron

11

問題がアンジェリカランガーGenerics FAQ #401で説明されています

クラスが同じジェネリック インタフェースの異なるインスタンスを実装することはできますか?

いいえ、タイプは、直接的または間接的に、同じ汎用インターフェイスの2つの異なるインスタンシエーションから派生してはなりません。

この制限の理由 は、タイプ消去による翻訳です。 を消去した後、同じ汎用インタフェースの異なるインスタンス化 が同じ生の型に崩壊します。実行時には、異なるインスタンス化の間に区別がありません。

(私は非常に問題の全体説明をチェックアウトをお勧めします:それは私が引用されたものよりも面白い)

この制限を回避するために、次のことを試すことができます。

public class Player<E extends Player> extends Participant implements Comparable<E> { 
    // ... 
    public int compareTo(E otherPlayer) { 
     Integer _scoredGoals = this.scoredGoals; 
     return _scoredGoals.compareTo(otherPlayer.getPlayerGoals()); 
    } 
    // ... 
} 


public class Goalkeeper extends Player<Goalkeeper> { 
    // ... 
    @Override 
    public int compareTo(Goalkeeper otherGoalkeeper) { 
     Integer _missedGoals = this.missedGoals; 
     return _missedGoals.compareTo(otherGoalkeeper.getMissedGoals()); 
    } 
    // ... 
} 
+0

+1 Angelika Langerからこのトピックの徹底的な情報源に言及してください。 – Kjellski

関連する問題