不能与父子孙继承进行比较
给出以下代码:
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
不会遵守。
当我尝试编译该代码时,Eclipse 会抛出:
The interface Comparable cannot be implemented more than once with
different arguments: Comparable<Player> and Comparable<Goalkeeper>
我不想与 Player
进行比较,而是与 Goalkeeper
进行比较,并且仅与他进行比较。
我做错了什么?
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
won't complie.
When I try to compile that code the Eclipse throws:
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 him.
What am I doing wrong ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Angelika Langer 的 泛型常见问题解答 #401 中描述了该问题:
(我强烈建议您查看问题的完整描述:它比我引用的内容更有趣。)
为了解决此限制,您可以尝试以下操作:
The problem is described in Angelika Langer's Generics FAQ #401:
(I highly recommend checking out the whole description of the problem: it's more interesting than what I've quoted.)
In order to work around this restriction, you can try the following:
就您的设计逻辑而言,您没有做错任何事情。然而,Java 有一个限制,阻止您实现具有不同类型参数的相同泛型接口,这是由于它实现泛型的方式(通过类型擦除)造成的。
在您的代码中,
Goalkeeper
继承自Player
它的Comparable
实现,并尝试添加一个Comparable;
自己的;这是不允许的。解决此限制的最简单方法是覆盖
Goalkeeper
中的Comparable
,将传入的玩家投射到Goalkeeper
,然后进行比较传给这个
守门员。编辑
As far as the logic of your design goes, you are not doing anything wrong. However, Java has a limitation that prevents you from implementing the same generic interface with different type parameters, which is due to the way it implements generics (through type erasure).
In your code,
Goalkeeper
inherits fromPlayer
its implementation ofComparable <Player>
, and tries to add aComparable <Goalkeeper>
of its own; this is not allowed.The simplest way to address this limitation is to override
Comparable <Player>
in theGoalkeeper
, cast the player passed in toGoalkeeper
, and compare it tothis
goalkeeper.Edit
我想在现有的好的答案的基础上补充两点。
您的设计有缺点
如您所知,您的设计不可能用 Java 实现。这是 Java 泛型的限制。让我们暂时设想一下如果可能的话。我认为这意味着许多人会感到惊讶和/或困惑的一些行为。
根据您的设计,假设我们有:
我们可以更进一步:
现在我们(仅)用守门员填充两个列表并对它们进行排序。现在,
list1
应该使用Goalkeeper.compsreTo()
进行排序,list2
可能使用Player.compareTo()
进行排序。开始变得混乱了,不是吗?这样的设计你想要吗?您是否更喜欢一种更明确何时使用哪种比较方式的方法? (是的,我知道,您无法通过变量list1
和list2
填充列表。您必须先填充列表,然后再将它们分配给这两个变量。)解决方案
解决方案 1:使用
Comparator
代替其中一个compareTo
方法(或两者)。Comparator
或Comparator
或两者之一。例如:解决方案 2:为非守门员的球员引入一个单独的类。由于没有更好的词,我暂时将其称为
FieldPlayer
。FieldPlayer
和Goalkeeper
都应该是Player
的子类。FieldPlayer
实现了Comparable
,并且Goalkeeper
已经实现了Comparable
。现在Player
不需要实现Comparable
,并且避免了冲突。I would like to add two points to the existing good answers.
Your design has downsides
As you know, your design isn’t possible with Java. It’s a restriction with Java generics. Let’s for a moment play what if it had been possible. It would imply some behaviour that I think many would find surprising and/or confusing.
With you design, assume we have:
We can take it one step further:
Now we fill both lists with goalkeepers (only) and sort them. Now
list1
should be sorted usingGoalkeeper.compsreTo()
andlist2
probably usingPlayer.compareTo()
. It’s beginning to be confusing, isn’t it? Would you want such a design? Would you prefer one where you are more explicit about which way to compare is used when? (Yes, I know, you cannot fill the lists through the variableslist1
andlist2
. You would have to fill the lists before assigning them to those two variables.)A couple of solutions
Solution 1: Instead of one of your
compareTo
methods (or both of them) use aComparator
. Either aComparator<Player>
or aComparator<Goalkeeper>
or one of each. For example:Solution 2: Introduce a separate class for players that are not goalkeepers. I am calling it
FieldPlayer
for now for lack of a better word. BothFieldPlayer
andGoalkeeper
should be subclasses ofPlayer
.FieldPlayer
implementsComparable<FieldPlayer>
andGoalkeeper
already implementsComparable<Goalkeeper>
. NowPlayer
doesn’t need to implementComparable
, and the conflict is avoided.