我正在玩仿制药,我发现了一个我无法弄清楚的问题。 请看一下这段代码:
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;
}
}
基本上,MyP
是P<MyO, MyResource>
的子类,而P<Operation<MyResource>, MyResource>
又是A.doIt
的子类
B.doIt
。换句话说,我们在{{1}}中返回{{1}}返回类型的子类。但是,编译器仍在抱怨。
答案 0 :(得分:5)
问题是MyP
是P<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有正确的想法。