I was playing around with generics, and I found a problem I really can't figure out. Please take a look at this code:
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;
}
}
So basically, MyP
is a subclass of P<MyO, MyResource>
which in turn is a subclass of
P<Operation<MyResource>, MyResource>
. In other words, we are returning a subclass of A.doIt
return type in B.doIt
. But nevertheless, the compiler is complaining.
Can you help me to understand this ? Thanks.
Since, boolean </: void (read: boolean isn't subtype of void ), compiler raises the "return type incompatible" error. This is neither overloading nor overriding. We cannot overload on the return type and we cannot override with different different return types ( unless they are covariant returns wef Java 1.5 ).
When we are overriding a method then we must keep three things in mind. The method in the subclass must have the same name as the method present inside the superclass. The method in the subclass should have the same number of parameters.
The sub class cannot declare a method with the same name of an already existing method in the super class with a different return type. However, the subclass can declare a method with the same signature as in super class. We call this "Overriding".
We cannot overload on the return type and we cannot override with different different return types ( unless they are covariant returns wef Java 1.5 ). Thanks for contributing an answer to Stack Overflow!
The problem is that MyP
is a P<MyO,>
, which is not the same as a P<Operation<MyResource>,>
(even though it does inherit it).
You need to change the abstract method's return type to be covariant in that parameter:
abstract class A<R> {
abstract P<? extends Operation<R>, R> doIt();
}
Now, MyP
is convertible to the base return type, so everything works fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With