我有一个相当奇怪的问题。考虑以下两个类:
public class Node<T> {
private Node<T> parent;
private Node<T> left;
private Node<T> right;
private T data;
public Node(Node<T> parent, T data) {
this.parent = parent;
this.data = data;
}
public Node<T> getParent() {
return parent;
}
public void setParent(Node<T> parent) {
this.parent = parent;
}
public Node<T> getLeft() {
return left;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public Node<T> getRight() {
return right;
}
public void setRight(Node<T> right) {
this.right = right;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
和
public class RedBlackNode<T> extends Node<T> {
private Color color;
public RedBlackNode(Node<T> parent, T data) {
super(parent, data);
this.color = Color.Black;
}
public RedBlackNode(Node<T> parent, T data, Color color) {
super(parent, data);
this.color = color;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
我的问题是......我有什么方法可以写:
RedBlackNode<Whatever> x = y.getLeft();
其中y是RedBlackNode
,无需使用:
RedBlackNode<Whatever> x = (RedBlackNode<Whatever>) y.getLeft();
并且,无需覆盖RedBlackNode类中的getter / setter?
我的意思是,我只想以某种方式让RedBlackNode“意识到”它是一个RedBlackNode,并且知道它的所有子/父实际上也是RedBlackNodes。我不确定但也许某种程度上可能以某种方式在Node类之上添加一个新的抽象层?
泰!
稍后编辑:
感谢您提供的所有快速答案,这是我目前所做的:
public abstract class AbstractNode<T, U extends AbstractNode<T, U>> {
private AbstractNode<T, U> parent;
private AbstractNode<T, U> left;
private AbstractNode<T, U> right;
private T data;
public AbstractNode(AbstractNode<T, U> parent, T data) {
this.parent = parent;
this.data = data;
}
public AbstractNode<T, U> getParent() {
return parent;
}
public void setParent(AbstractNode<T, U> parent) {
this.parent = parent;
}
public AbstractNode<T, U> getLeft() {
return left;
}
public void setLeft(AbstractNode<T, U> left) {
this.left = left;
}
public AbstractNode<T, U> getRight() {
return right;
}
public void setRight(AbstractNode<T, U> right) {
this.right = right;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
public class RedBlackNode<T extends Element> extends AbstractNode<Element, RedBlackNode<Element>> {
private Color color;
public RedBlackNode(RedBlackNode<Element> parent, T data) {
super(parent, data);
this.color = Color.Black;
}
public RedBlackNode(RedBlackNode<Element> parent, T data, Color color) {
super(parent, data);
this.color = color;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
public class Node<T> extends AbstractNode<T, Node<T>> {
public Node(AbstractNode<T, Node<T>> parent, T data) {
super(parent, data);
}
}
但是,我需要创建两种类型的树。一个简单的二进制搜索树,它只有Node节点的实例,并且如预期的那样,只有RedBlackNode实例作为节点的Red Black Tree。
我为这些树做了一个抽象类(有更多的方法,这是修剪后的版本)但是我担心我错过了一些东西,因为我似乎将这个Node<Element>
作为类定义中的泛型类型
public abstract class Tree<T extends AbstractNode<Element, Node<Element>>> {
protected T root;
public T getRoot() {
return this.root;
}
public abstract T search(T n, int key);
public abstract T insert(Element e, T cRoot);
}
我在这里缺少什么?如何最好地模拟这个?
稍后编辑2:
我目前有:
public abstract class AbstractNode<E extends Element, U extends AbstractNode<E, U>> {
private U parent;
private U left;
private U right;
private E data;
public AbstractNode(U parent, E data) {
this.parent = parent;
this.data = data;
}
public U getParent() {
return parent;
}
public void setParent(U parent) {
this.parent = parent;
}
public U getLeft() {
return left;
}
public void setLeft(U left) {
this.left = left;
}
public U getRight() {
return right;
}
public void setRight(U right) {
this.right = right;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
}
public class Node<E extends Element> extends AbstractNode<E, Node<E>> {
public Node(Node<E> parent, E data) {
super(parent, data);
}
}
public class RedBlackNode<E extends Element> extends AbstractNode<E, RedBlackNode<E>> {
private Color color;
public RedBlackNode(RedBlackNode<E> parent, E data) {
super(parent, data);
this.color = Color.Black;
}
public RedBlackNode(RedBlackNode<E> parent, E data, Color color) {
super(parent, data);
this.color = color;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
树类:
public abstract class Tree<E extends Element, T extends AbstractNode<E, T>> {
protected T root;
public T getRoot() {
return this.root;
}
public abstract T search(T n, int key);
}
和BinarySearchTreeClass
public class BinarySearchTree<Element> extends Tree<Element, Node<Element>> {
@Override
public Node<Element> search(Node<Element> n, int key) {
if (n == null || n.getData().getIntegerData() == key) {
return n;
}
return key < n.getData().getIntegerData() ? search( n.getLeft(), key) : search( n.getRight(), key);
}
}
为什么我在世界上Bound mismatch: The type Element is not a valid substitute for the bounded parameter <E extends Element> of the type Node<E>
。它是E extends Element
。这是不是意味着它也可以是Element
类型?
尽管如此,我尝试使用类似于扩展Element
但没有用的单独类的东西。
另外,我收到了The type parameter Element is hiding the type Element
,我不知道为什么......
我为此创建了GIST。
答案 0 :(得分:4)
如果您不介意将Node
拉出到抽象类中,您可以将类型指定为通用签名的一部分,如下所示:
public abstract class AbstractNode<T, U extends AbstractNode<T, U>> {
...
public U getLeft() {
...
}
...
}
// inherited getLeft() will return Node<T>
public class Node<T> extends AbstractNode<T, Node<T>> { ... }
// inherited getLeft() will return RedBlackNode<T>
public class RedBlackNode<T> extends AbstractNode<T, RedBlackNode<T>> { ... }
编辑:对于您的树,您可以为每个节点类型创建一个单独的树,或者如果您想重用基本功能,您可以执行以下操作:
// base functionality goes here, T is the element type, U is the node type
public abstract class Tree<T, U extends AbstractNode<T, U>> { ... }
public class BinarySearchTree<T> extends Tree<T, Node<T>> { ... }
public class RedBlackTree<T> extends Tree<T, RedBlackNode<T>> { ... }
或者如果您只想共享方法签名,则将Tree
设为接口而不是抽象类。或者更好的是,有一个Tree
接口和一个实现共享功能的AbstractTree
抽象类。