Java 重写参数类型引用自己的类的方法
我有以下java代码:Java 重写参数类型引用自己的类的方法,java,Java,我有以下java代码: public class TreeNode<T> { public TreeNode<T> getParent() { return null; } public void setParent(TreeNode<T> parent) { } public List<TreeNode<T>> getChildren() { return
public class TreeNode<T> {
public TreeNode<T> getParent() {
return null;
}
public void setParent(TreeNode<T> parent) {
}
public List<TreeNode<T>> getChildren() {
return null;
}
public void setChildren(List<TreeNode<T>> children) {
}
public T getData() {
return null;
}
public void setData(T data) {
}
}
公共类树节点{
公共树节点getParent(){
返回null;
}
public void setParent(TreeNode parent){
}
公共列表getChildren(){
返回null;
}
公共子项(列出子项){
}
公共T getData(){
返回null;
}
公共无效设置数据(T数据){
}
}
现在,我想创建一个扩展上述类的类,如下所示:
public class BinaryTreeNode<T> extends TreeNode<T> {
public BinaryTreeNode<T> getLeftChild() {
return null;
}
public void setLeftChild() {
}
public BinaryTreeNode<T> getRightChild() {
return null;
}
public void setRightChild() {
}
@Override
public void setChildren(List<BinaryTreeNode<T>> children) {
}
}
公共类二进制TreeNode扩展TreeNode{
公共二进制树节点getLeftChild(){
返回null;
}
公共void setLeftChild(){
}
公共二进制树节点getRightChild(){
返回null;
}
公共无效setRightChild(){
}
@凌驾
公共子项(列出子项){
}
}
但是,最后一个方法不会编译,因为参数children
不是List
类型。我理解为什么会发生这种情况(因为List
不被视为List
的子类型),但解决这种问题的最佳方法是什么
我知道我可以将
children
参数定义为List
类型,但是如果可能的话,我想强制它为List
类型。问题不在于列表不是子类,而是因为您无法重写方法并向上转换其参数
如果您有以下课程:
public class A
{
public void f(A a) {}
}
public class B extends A
{
public void problem(){}
public void f(B a)
{
a.problem();
}
}
由于B从A扩展而来,因此可以运行以下代码:
A a1 = new B();
A a2 = new A();
a1.f(a2);
当该代码运行时,它将尝试在没有该函数的实例上执行函数“problem”。
这就是为什么通常不能用继承原始类型的类重写参数
现在,您可以将参数保留为List>children,但是您可能会得到非二进制的节点,我假设您不需要
如果您确定这就是您希望继承的方式,您可以在方法开头检查“children”的类型,如果不合适,则抛出异常。总结shmosel的建议:
public class TreeNode<T, N extends TreeNode<T, N>> {
public N getParent() { return null; }
public void setParent(N parent) {}
public List<N> getChildren() { return null; }
public void setChildren(List<N> children) {}
public T getData() { return null; }
public void setData(T data) {}
}
公共类树节点{
public N getParent(){return null;}
public void setParent(N parent){}
公共列表getChildren(){return null;}
public void setChildren(列出子项){}
public T getData(){return null;}
公共void setData(T data){}
}
缺点是您的节点现在必须使用“冗余”泛型类型进行分类。这是因为您试图反驳这样一个事实,即子类可以充当超类的对象
您的二进制节点类如下所示:
class BinaryTreeNode<T> extends TreeNode<T, BinaryTreeNode<T>>
类BinaryTreeNode扩展了TreeNode
作为另一种选择和进一步阅读,请尝试以下文章:
尝试列表添加标识当前类型的通用参数,例如,
class TreeNode
。并使方法setChildren(List children)
。如果BinaryTreeNode的唯一子元素是BinaryTreeNodes,那么叶子是什么类型?@andythonas BinaryTreeNodes,但没有自己的子元素。@shmosel我也有同样的想法,但您需要更改子元素的子元素类型。正如你所写的,孩子们有相同类型的孩子。实际上,它应该是类TreeNode
,因为祖父可能不知道孙子的类型。您不需要公开子类中的第二个参数。请参阅我上面的评论。谢谢,单击花了一些时间。父类型可能也应该是N
。不过,我认为仍然可以通过游戏将此结构与节点混合。是的,这是Java中泛型不可避免的现实。