覆盖参数类型引用其类的方法

时间:2017-05-15 17:48:29

标签: java

我有以下java代码:

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) {

    }
}

现在,我想创建一个扩展上面一个的类,如下所示:

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) {

    }

}

但是,最后一种方法不会编译,因为参数children不是List<TreeNode<T>>类型。我理解为什么会发生这种情况(因为List<BinaryTreeNode<T>>不被视为List<TreeNode<T>>的子类型),但修复此类内容的最佳方法是什么?

我知道我可以将children参数定义为List<TreeNode<T>>类型,但如果可能,我希望将其强制为List<BinaryTreeNode<T>>类型。

2 个答案:

答案 0 :(得分:0)

这个问题不是来自不是子类的列表,而是因为你不能覆盖一个方法并将其参数翻转。

如果您有以下课程:

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);

当该代码运行时,它将尝试在没有它的A实例上执行函数“problem”。 这就是为什么通常你不能用继承原始类型的类覆盖参数。

现在,您可以将参数保留为List&gt;孩子,但是你可能会得到非二进制的节点,我认为你不需要它。

如果您确定这是您希望继承的方式,则可以在方法开头检查“children”的类型,如果不适合则抛出异常。

答案 1 :(得分:0)

总结一下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) {}
}

缺点是您的节点现在必须输入&#34;冗余&#34;通用类型。那是因为你试图反击子类可以作为超类对象的事实。

你的二进制节点类看起来像这样:

class BinaryTreeNode<T> extends TreeNode<T, BinaryTreeNode<T>>

作为替代方案并进一步阅读,请尝试以下文章:

https://www.sitepoint.com/self-types-with-javas-generics/