Impossible to use comparable to inheritance of grandson-son-grandson

Given the following code:

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 } 

The problem is that Goalkeeper will not match.

When I try to compile this code, Eclipse is called:

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

I'm not trying to compare with Player , but with Goalkeeper and only with it.

What am I doing wrong?

+7
source share
2 answers

As for the logic of your design, you are not doing anything wrong. However, Java has a limitation that prevents you from implementing the same general interface with different type parameters, which is related to how it implements generics (via type erasure).

In your code, Goalkeeper inherits from its Player implementation of Comparable <Player> and tries to add its own Comparable <Goalkeeper> ; it is not allowed.

The easiest way to eliminate this restriction is to override Comparable <Player> in Goalkeeper , transfer the player transferred to Goalkeeper , and compare it with this goalkeeper.

Edit

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

The problem is described in Angelika Langer General Questions # 401 :

Can a class implement different instances of the same generic interface?

No, a type should not flow directly or indirectly from two different instances of the same common interface.

The reason since this restriction is a translation by type of erasure. After the type to erase different instances of the same common interface, collapse to the same raw type. At run time, there is no difference between different instances.

(I highly recommend checking the entire description of the problem: this is more interesting than what I quoted.)

To get around this limitation, you can try the following:

 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()); } // ... } 
+11
source

All Articles