我试图实现一棵树,使节点是通用的:
public class BinarySearchTree<U extends BinarySearchTree.Node, T extends Comparable<? super T>>
{
public U root;
...
public class Node {
T data;
U left;
U right;
public Node(T data) {
this.data = data;
left = null;
right = null;
}
}
}
但是,当我尝试用一种方法进行赋值时,我得到了“预期的U,但发现BinarySearchTree.Node:
public void display(U root) {
if (root != null) {
display(root.left); // gives compile time error
System.out.print(" " + root.data);
display(root.right); // gives compile time error
}
}
最佳答案
由于Node
不是静态的,因此每个Node
实例都属于一个包含BinarySearchTree
的实例。但是,使用泛型无法指定它属于哪个泛型。因此,如果指定BinarySearchTree.Node
,则它可以属于任何BinarySearchTree
。由于您还使用了原始类型(请不要忽略警告!),因此不知道U
是什么。因此,Java无法检查root.left
和root.right
的类型是否相同,这就是为什么会出现此错误。
您可以通过如下指定类来修复编译错误:
class BinarySearchTree<U extends BinarySearchTree<U,T>.Node, T extends Comparable<? super T>>
{ ... }
但这不能解决潜在的问题,即节点可以属于任何包含
BinarySearchTree
的节点,而这可能不是您想要的。如果您确实想使用通用节点类型,则可以将其设置为静态,这样它就不再属于包含实例了:
public static class Node<U,T>
{
...
}
但是我质疑是否首先需要有一个通用节点类。通常,此类节点被视为实现细节,您希望完全控制从您的类中创建它们。这不适用于通用节点,因为您的类不知道要实例化哪种节点。
因此,我将按以下方式定义您的
BinarySearchTree
类:public class BinarySearchTree<T extends Comparable<? super T>>
{
private Node<T> root;
private static class Node<T>
{
T data;
Node<T> left;
Node<T> right;
}
...
}