在接口中实现Comparable

5

我正在使用一个接口来调用特定的类。问题是,该类本身实现了Comparable接口,但因为我是通过不同的接口引用该类,编译器并不知道它实现了Comparable接口。我相信这个问题有一个简单的解决办法...但我现在想不出来。

5个回答

8

所有实现该接口的对象是否也都实现了 Comparable<T> 接口?如果是的话,我建议你将这个接口扩展为 Comparable<T> 接口。

否则,如果你碰巧知道在 这种情况 下可以使用,那么你可以强制转换为 Comparable<T>。当然,这会失去一些编译时类型安全性,但这是这个问题的本质。


是的,但它没有起作用。我有一个公共接口Individual<T> extends Comparable<Individual<T>>,但当我尝试对List<Individual<?>>进行排序时,它不起作用。 - Ben B.
@Ben:如果你在问题中提供了一些示例代码,那就更好了...最好是一个简短但完整的示例。这应该是一个相当容易重现的问题。 - Jon Skeet
我已经尝试了很多东西,所以我希望这个问题足够清楚。 - Ben B.

1

这对我来说似乎很奇怪...如果您有以下代码的主函数,您可以使用下面的父接口和子类使其工作...但是有一个奇怪之处在于,您可以尝试将ChildA与ChildB进行比较,这可能是没有意义的。

也许如果您给出了类/接口正在执行的提示,我们可以提供更好的答案。

public class Main
{
    public static void main(final String[] argv)
    {
        Parent x;
        Parent y;

        x = new ChildA();
        y = new ChildA();
        x.compareTo(y);
    }
}

abstract interface Parent
    extends Comparable<Parent>
{
}

class ChildA
    implements Parent
{
    public int compareTo(Parent o)
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

class ChildB
    implements Parent
{
    public int compareTo(Parent o)
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

我正在比较相同类型的类,但程序设计以这样的方式设计,该类类型是一个参数,因此一些类引用接口。 - Ben B.
就像 List<T> listA = ArrayList<T>() 和 List<T> listB = LinkedList<T>() 一样有用。 - Ben B.
嗯,如果我这样做public interface MyInterface extends Comparable<MyIterface<?>>,它就可以工作。 - Ben B.

1

你可以使用一些奇特的泛型。比如说,主接口是 Lickable(它定义了一个方法 lick()),而你想要一个处理既是 Lickable 又是 Comparable 的对象的方法。你可以这样写:

public <LickableAndComparable extends Lickable & Comparable<LickableAndComparable>> void lickGreater(LickableAndComparable a, LickableAndComparable b) {
    if (a.compareTo(b) > 0) a.lick();
    else b.lick();
}

然后您可以使用任何类型的对象调用它,该对象既是Lickable又是Comparable。 请注意,仅当两个参数共享的类型既是Lickable又是Comparable时,它才有效。 如果您只考虑一个类,则这应该没问题。 如果您对该方法的使用变得复杂,则可能会遇到引发偏头痛的编译器错误。


难道没有标准的方法来做这件事吗? - Ben B.

1
我建议您使用 Comparator。您可以使用 sort(list, Comparator) 方法。您的比较器实现将把类强制转换为 Comparable 并使用其 compare 方法。这样编译器就会满意,并且您可以重用现有的 compare 方法实现。

0

可比较接口有些棘手。一般来说,如果你将一个接口标记为可比较的,那么任何正确的实现只能使用该接口中的方法来执行比较。否则,这种关系就无法成为反对称关系——这是保持一致排序的必要条件。

因此,在将接口标记为可比较之前,请三思而后行。

然而,在您的情况下,如果您确定没有混合使用不同的接口实现,则可以使用一种解决方法:

interface Foo {
}

interface Bar extends Foo, Comparable<Bar> {
}


class FooComparator<T extends Foo & Comparable<T>> implements Comparator<T> {

    @Override
    public int compare(T arg0, T arg1) {
        return arg0.compareTo(arg1);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接