覆盖扩展类的compareTo - 发生了什么?

时间:2013-11-25 23:32:14

标签: java interface extends comparable compareto

我一直试图以这种方式覆盖compareTo: 这是原作:

@Override
public int compareTo(ProductPart6 s)
{
    return this.getproductName().compareTo(s.getproductName());

}

这是我试图用以下方法覆盖它: 它会抛出一个错误 SubClass类型的compareTo(SubClass)方法必须覆盖或实现超类型方法。

@Override
    public int compareTo(SubClass s)
    {
        return this.getTitle().compareTo(s.getTitle());

    }

我认为这是非常错误的。我的ProductPart6没有getTitle()并导致它

@Override
    public int compareTo(ProductPart6 s)
    {
        return this.getTitle().compareTo(s.getTitle());

    }

抛出错误(对于ProductPart6类型,未定义getTitle()) - 如果我在那里定义了它,那么就没有必要覆盖它。 我究竟做错了什么?我有SubClass扩展ProductPart6和ProductPart6实现Comparable - 我以为我可以在SubClass上实现它,但没有。那是不行的。

2 个答案:

答案 0 :(得分:4)

当一个类实现Comparable<T>时,您必须指定对象的类型(T),以便与您的类的实例进行比较。 compareTo的所有子实现也必须接受相同的类型参数T

让我们考虑两个类:

public class Alpha implements Comparable<Alpha> {
    @Override
    public int compareTo(Alpha a) {
        ...
    }
}

和...

public class Bravo extends Alpha {...}

如果您尝试覆盖compareTo中的Bravo,则必须提供Alpha类型的参数,因为Alpha是满足课程T的类型声明(包括implements Comparable)。否则,它不会覆盖超类型方法,因此编译器会抱怨@Override注释,这就是您在此处看到的内容。

在您的情况下,我认为您需要考虑ProductPart6SubClass是否足够兼容以便以这种方式使用。如果没有,请考虑使用单独的Comparator实例,或者重构以创建在两种情况下都满足T的公共类型。

答案 1 :(得分:2)

扩展@ ATG的答案:如果你有这个课程:

public class Alpha implements Comparable<Alpha> {
    @Override
    public int compareTo(Alpha a) {
        ...
    }
}

您可以在需要Comparable的上下文中使用此类,例如SortedSet<Alpha>但是当您拥有SortedSet<Alpha>时,该集合的元素可以是类Alpha 或任何子类,包括Bravo

public class Bravo extends Alpha {...}

由于集合中可以同时包含AlphaBravo类型的对象,因此集合操作需要能够以一种顺序将一种类型的对象与另一种类型的对象进行比较。它可能会调用

A.compare(B);

其中AAlphaBBravo。这将调用您在compareTo中编写的Alpha方法。它也可能会调用

B.compare(A);

其中AAlphaBBravo。这就是为什么声明

是错误的
@Override
public int compareTo(Bravo b) { ... }
Bravo类中的

,因为这会阻止调用B.compare(A)。你不仅需要这样声明:

@Override
public int compareTo(Alpha a) { ... }

当使用BravoAlpha调用时,它也必须正常工作。此外,Alpha中的方法必须在其参数为Bravo时正常工作,效果必须是compareTo为您提供正确的总排序,无论哪种类型的组合传递它。

如果你的意图是每个数组或集合只包含类为Alpha的对象,或者只包含类为Bravo的对象,那么你需要一些其他的机制来确保一切都是相同的类,或者根本不使用子类(这是我认为@ATG所得到的)。