我正在使用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>