我遇到了一个我们已经实现的树的问题,这是一个示例:
public interface TreeNode {
TreeNode getParent();
void setParent(TreeNode parent);
List<TreeNode> getChildren();
void setChildren(List<TreeNode> children);
}
所以,到现在为止这很容易,但是我们有一些树的变体,所以我们有一些这样的接口:
public interface TreeNodeWithX extends TreeNode {
String getX();
void setX(String x);
}
public interface TreeNodeWithY extends TreeNode {
Boolean getY();
void setY(Boolean y);
}
所以,我需要一个TreeNodeWithX对象(是的,它的实现)从其getParent方法返回一个TreeNodeWithX对象(与TreeNode接口中的其他方法相同)。
来自TreeNodeWithY的相同行为,getParent()应返回TreeNodeWithY。
我尝试过一些泛型方法,例如:
public interface TreeNode<T extends TreeNode> {
T getParent();
void setParent(T parent);
List<T> getChildren();
void setChildren(List<T> children);
}
但是,在实施方法的某些时候,我总是遇到麻烦。我的问题是,我是否使用我的通用界面正确的方式或我在这里做错了什么?
这种递归泛型引用并没有真正帮助我......
答案 0 :(得分:6)
您希望您的节点处理通用数据,而不是只生成要保留的通用TreeNode
。 IMO你的界面应该使用T
来处理数据并保留其他方法:
public interface TreeNode<T> {
TreeNode<T> getParent();
void setParent(TreeNode<T> parent);
List<TreeNode<T>> getChildren();
void setChildren(List<TreeNode<T>> children);
T getData();
void setData(T data);
}
现在,您可以TreeNode<String>
和TreeNode<Boolean>
getData
方法将返回String
或Boolean
(取决于传递的泛型类参数)。
TreeNode<String> treeNode = new SomeImplementationOfTreeNode<String>();
treeNode.setData("Hello world");
System.out.println(treeNode.getData()); // "Hello world"
答案 1 :(得分:4)
TreeNode
的类型应该是每个节点上保存的值的类型,而不是类型 TreeNode
(我们已经知道了)正在处理TreeNodes
)
试试这个:
/**
* A Node in a Tree
* @param <T> The type of the value held at each node
*/
public interface TreeNode<T> {
TreeNode<T> getParent();
void setParent(TreeNode<T> parent);
List<TreeNode<T>> getChildren();
void setChildren(List<TreeNode<T>> children);
// A getter/setter of type `T` to the node for the "value" held there.
T getValue();
void setValue(T value);
}
考虑省略setter并在实现中创建字段final
,将值传递给构造函数:
// Impl if TreeNode doesn't declare a setValue() method
public class MyTreeNode<T> implements TreeNode<T> {
final T value;
public MyTreeNode(T value) {
this.value = value;
}
// rest of impl
}
如果您只考虑一个实现,请考虑将TreeNode
作为一个类。
答案 2 :(得分:2)
TreeNode<T extends TreeNode>
不是正确的做法。如何使用单一界面:
public interface TreeNode<T> {
TreeNode<T> getParent();
void setParent(TreeNode<T> parent);
List<TreeNode<T>> getChildren();
void setChildren(List<TreeNode<T>> children);
T getValue();
void setValue(T x);
}