似乎您通常在不指定类型参数的情况下实现java.lang.Comparable
接口。
public abstract class Area implements Comparable {
@Override
public int compareTo(Object other) {
if (other instanceof Area)
return new Double(getArea()).compareTo(other.getArea());
return -1; // or something else
}
abstract public double getArea();
}
由于我只想将苹果与苹果进行比较,因此我认为指定类型是有意义的。
public abstract class Area implements Comparable<Area> {
@Override
public int compareTo(Area other) {
// ...
如果我想介绍另一个类来比较Area
,我想我可以执行以下操作:
public abstract class Area implements Comparable<Area>, Comparable<Volume> {
@Override
public int compareTo(Area other) {
// ...
}
@Override
public int compareTo(Volume other) {
// ...
}
}
但是Java编译器告诉我:
Area.java:2: error: repeated interface
public abstract class Area implements Comparable<Area>, Comparable<Volume> {
^
Area.java:2: error: Comparable cannot be inherited with different arguments: <Area> and <Volume>
- 指定泛型接口的类型参数是否有任何缺点?
- 为什么 Java 不允许我进行这种多重实现?
注意:我使用的是 Java 版本 1.7.0_45
-
不,这不是指定泛型的缺点 - 它实际上是一个功能。另外,我不记得在接口中使用泛型有任何缺点,除了众所周知的事实,你不能实例化泛型类型或创建泛型数组(但这更多的是实现的问题,而不是接口本身)。
-
这是由于类型擦除。 对于 VM,
Comparable<Area>
和Comparable<Volume>
本质上是同一类,并且在检查有效性后不久,编译器也是如此。
如果你想实现两个不同的可比较接口,只需对它们使用 Comparator
s - 在类中维护组合通常比继承更容易。
对于某些应用程序(在运行时区分泛型),您也可以尝试对它们进行子类化,例如 ComparableArea extends Comparable<Area>
& ComparableVolume extends Comparable<Volume>
,但在这种情况下,这会造成比解决 IMO 更多的麻烦,因为您仍然会收到Comparable cannot be inherited with different arguments
错误 - 但至少您可以通过例如 instanceof
.
我认为java这样说相关的类是可以比较的,但是使用人工比较器,我们可以在不相关的类之间进行更多的比较。所以我们应该实现相关类(同一继承层次结构中的类)的泛型接口。如果我们想添加一个人工实现,添加一个可以传递的接口(所以有一对接口系列,如 Comparable 和 Comparator)。