为什么 compareTo() 中的参数不接受类名,而只接受 Object



我正在使用Java中的优先级队列实现Dijkstra算法。我正在使用"节点"类的对象作为队列。为了实现这一点,我正在覆盖 Node 类中的 compareTo(( 方法。如果我使用"对象 obj"作为 compareTo(( 的参数,它工作正常。但是,当我给出"Node obj"作为参数来比较To((时,正在出现一个错误,说"节点不是抽象的,不会覆盖抽象方法compareTo(Object(在可比性中。从我所读到的内容来看,这应该是可能的。怎么了?

    public class Node implements Comparable  
    {   int key;  
        int val;  
        public Node(int v)  
        {   val=v;  
            key=0;  
        }
    @Override
        public int compareTo(Object obj)
        {   Node nd=(Node) obj;
            return this.key-nd.key;
        }
        public Node(int v, int k)
        {   val=v;
            key=k;
        }
    } 

如果我这样做(下面的代码(,而上面的代码工作正常,则会显示错误。

@Override
    public int compareTo(Node obj)
    {  
        return this.key-obj.key;
    }

可比较的是指定参数化类型的接口:

public interface Comparable<T>{...

我们也可以说这是一个泛型类(更短(。

所以宣布public class Node implements Comparable{...
表示您要实现与非特定类型相当的可比性。

事实上,对于编译器来说,public class Node implements Comparable{ 是一回事

public class Node implements Comparable<Object>{

因此,编译器希望在类中找到public int compareTo(Object obj)方法。
而编译错误消息:

"节点不是抽象的,不会覆盖抽象方法 比较(对象(在可比性中。

指定要在要实现的可比较接口中使用的类:(此处public class Node implements Comparable<Node>{(。

编译器将期望找到实现的方法:

public int compareTo(Node obj)

改为执行此操作,

public class Node implements Comparable <Node>{

这是因为 Comparable 是一个通用接口,并且如文档所述,采用参数T

T - 可以与此对象进行比较的对象类型

如果没有此参数,它将解析为 Object ,这是您不需要的。

因为未键入已覆盖的接口(可比较(。 您需要使用 Java 泛型来声明要比较的类型:

public class Node implements Comparable<Node>

这表示您希望Comparable Node类型,并允许您执行

public int compareTo(Node obj)

如果您不将其泛型化,那么您实际上是在执行@Override然后更改方法签名,编译器会将其标记为错误,因为您正在对不在接口中的方法执行@Override

Interface Comparable<T>

是一个泛型接口,由于您没有绑定任何类型的,因此默认为对象绑定所需的类型(Comparable<Node>(,您会没事的。

您尝试实现的接口 - Comparable 是通用的。如果未指定任何泛型参数,则泛型参数默认为 Object

根据接口,Comparable<Object>应该有这样的方法:

public int compareTo(Object o);

但是在你的代码中,你只有这个方法:

public int compareTo(Node obj);

编译器认为它们是不同的,因此抱怨。

若要解决此问题,只需指定泛型类型参数。这没什么难的:

public class Node implements Comparable<Node>

最新更新