【发布时间】:2015-08-24 15:54:31
【问题描述】:
我有一个很奇怪的问题。考虑以下两个类:
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,并且知道它的所有子/父实际上也是 RedBlackNode。我不确定,但也许以某种方式在 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);
}
}
但是,我需要创建 2 种类型的树。一个简单的二叉搜索树,它只有 Node 类的实例作为节点,并且正如预期的那样,红黑树只有 RedBlackNode 的实例作为节点。
我为这些树创建了一个抽象类(有更多方法,这是修剪后的版本),但我担心我遗漏了一些东西,因为我似乎将这个 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。
【问题讨论】:
-
最简单的解决方案(仍然是样板)是覆盖超类方法并将返回类型更改为
RedBlackNode。 -
是的,我知道,但是有什么方法可以避免覆盖这些方法吗?
-
也许您提取样板代码并将其添加为具有泛型的接口?因此,您为 Node 和 NodeGetters
或父类实现 NodeGetters 。 -
是的,但它们很烂:( stackoverflow.com/questions/10968557/…
-
您的抽象类没有正确的泛型。请参阅 SamYonnou 的示例:
AbstractNode<T, U extends AbstractNode<T, U>>。T是每个节点中数据的类型。U——我个人称它为N——是U extends AbstractNode<T,U>类型的关联节点(父、左、右)的类型(也就是说“AbstractNode的某些子类型,其中T是其中的数据,其相关节点(父、左、右)也是U") 类型。如果这一切听起来有点递归,那是因为它是。