在Java中覆盖Generic类的方法时,返回类型不兼容

时间:2014-03-13 15:55:46

标签: java generics override

我正在玩仿制药,我发现了一个我无法弄清楚的问题。 请看一下这段代码:

class Operation<R> {
}

class P<O extends Operation<R>, R> {
}

class MyResource {
}

class MyO extends Operation<MyResource> {
}

class MyP extends P<MyO, MyResource> {
}

abstract class A<R> {
    abstract P<Operation<R>, R> doIt();
}

class B extends A<MyResource> {
    @Override
    MyP doIt() {
    /*
        the compiler is complaining about the above line:
        The return type is incompatible with A<MyResource>.doIt()
    */
        return null;
    }
}

基本上,MyPP<MyO, MyResource>的子类,而P<Operation<MyResource>, MyResource>又是A.doIt的子类 B.doIt。换句话说,我们在{{1}}中返回{{1}}返回类型的子类。但是,编译器仍在抱怨。

你能帮我理解一下吗? 感谢。

2 个答案:

答案 0 :(得分:5)

问题是MyPP<MyO,>,与P<Operation<MyResource>,>不同(即使它继承了它)。
您需要将抽象方法的返回类型更改为该参数中的协变:

abstract class A<R> {
    abstract P<? extends Operation<R>, R> doIt();
}

现在,MyP可以转换为基本返回类型,因此一切正常。

答案 1 :(得分:2)

您声称P<MyO, MyResource>P<Operation<MyResource>, MyResource>的子类是不正确的。这些类型的关系在Java中不成立,原因是泛型类可以以协变或逆变方式(或两者)使用其类型参数。如果用法是严格协变的,那么您提出的自动子类型关系将是不合理的。 @SLaks有正确的想法。