Java覆盖问题(确定实现类中的参数/返回类型)

时间:2019-02-17 22:52:21

标签: java

我真的不明白为什么Java中不允许这样做?!

界面

package api;

public interface TreeNode {
    public boolean isValidBST(TreeNode root);
}

实施

package impl;

public class TreeNodeImpl implements api.TreeNode {
    @Override
    public boolean isValidBST(TreeNodeImpl root) {
        return false;
    }
}

根据我的理解,该错误没有意义

enter image description here

1 个答案:

答案 0 :(得分:0)

根据接口定义,接口TreeNode的每个实现都必须具有采用isValidBST(...)作为参数的方法TreeNode。另一方面,您的实现TreeNodeImpl仅将TreeNodeImpl作为参数(所有TreeNode的子集)。例如,如果还有其他class OtherTreeNodeImpl implements TreeNode,则呼叫

TreeNode node = new TreeNodeImpl();
node.isValidBST(new OtherTreeNodeImpl());

将导致编译时错误,尽管仅在查看接口时它们看起来就很好。这就是为什么编译器(正确地)声称您的方法没有覆盖父方法的原因。


您可以通过指定泛型来解决问题

public interface TreeNode<T extends TreeNode<T>> {
    public boolean isValidBST(T root);
}

public class TreeNodeImpl implements TreeNode<TreeNodeImpl> {
    @Override
    public boolean isValidBST(TreeNodeImpl root) {
        return false;
    }
}

但是对我来说,这似乎是一个肮脏的hack。界面应减少摩擦,但是此界面会引入摩擦。因此,您应该以这样一种方式设计接口TreeNode,即只能使用方法TreeNodeisValidBST(...)中定义的方法。如果设计正确,则应该能够在isValidBST(...)中将TreeNode的实现指定为default method