【问题标题】:Why is it not possible to implement Comparable<T> multiple times?为什么不能多次实现 Comparable<T> ?
【发布时间】:2014-11-20 14:24:43
【问题描述】:

您似乎通常在没有指定类型参数的情况下实现了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 不允许我进行这种多重实现?

注意:我使用的是 Java 版本 1.7.0_45

【问题讨论】:

  • 我认为更好的问题是,您为什么认为这会有益? newYork.compareTo(eleven) 怎么会是苹果对苹果? :-)

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


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

  2. 这是由于type erasureComparable&lt;Area&gt;Comparable&lt;Volume&gt; 对于 VM 来说本质上是同一个类,并且在检查有效性后不久,对于编译器也是如此。

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

对于某些应用程序(在运行时区分泛型),您也可以尝试对它们进行子类化,例如ComparableArea extends Comparable&lt;Area&gt; & ComparableVolume extends Comparable&lt;Volume&gt;,但在这种特殊情况下,这会比解决 IMO 造成更多的麻烦,因为你仍然会得到 Comparable cannot be inherited with different arguments 错误 - 但至少你可以通过例如区分这些接口instanceof.

【讨论】:

  • 我同意。如果 OP 希望能够比较不同类型且不共享公共超类的多个项目,最好只写一个知道如何做到这一点的Comparator。您的 Area 类不应该真的(IMO)需要知道 Volume 类的存在,也不应该知道如何比较自己。如果他们这样做了,那么您的Volume 类是否也需要同时实现Comparables?随着您添加更多类型,您可以看到这将如何迅速失控。
  • @CraigOtis 我完全同意;我会将其作为注释添加到我的答案中。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2019-05-02
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多