为什么不能多次实现Comparable <t>?</t>

时间:2014-11-20 14:24:43

标签: java interface compare comparable multiple-interface-implem

看起来你通常在没有指定类型参数的情况下实现了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>
  1. 是否存在指定通用接口的类型参数的缺点?
  2. 为什么Java不允许我这种多重实现?
  3. 注意:我使用的是Java版本1.7.0_45

2 个答案:

答案 0 :(得分:4)

  1. 不,指定通用的缺点 - 它实际上是功能。另外,我不记得在接口中使用泛型有任何缺点,除了众所周知的事实,你不能实例化泛型类型也不能创建一个通用数组(但这更多的是实现问题,而不是接口本身)。

  2. 归功于type erasureComparable<Area>Comparable<Volume>本质上是VM的类,并且在检查有效性后不久,也用于编译器。

  3. 如果你想要实现两个不同的可比较接口,只需使用Comparator - 它们通常比类中的继承更容易维护组合。

    对于某些应用程序(在运行时区分泛型),您也可以尝试对它们进行子类化,例如: ComparableArea extends Comparable<Area>&amp; ComparableVolume extends Comparable<Volume>,但在这种特定情况下,这会导致比解决IMO更麻烦,因为您仍然会遇到Comparable cannot be inherited with different arguments错误 - 但至少您可以通过以下方式区分这些接口: instanceof

答案 1 :(得分:0)

我认为这种方式java说相关的类可以是Comparable,但是使用人工Comparator我们可以在不相关的类之间进行更多的比较。 所以我们应该实现相关类的通用接口(同一继承层次结构中的类)。如果我们想要添加一个人工实现,添加一个可以传递的接口(所以有一对接口系列,如Comparable和Comparator)。