I have an inquiry about method overriding covariance .. Let's say we have two classes as follows:
class Parent {
Object getSomething(){
return 10;
}
}
class Child extends Parent {
Integer getSomething() {
return 10;
}
}
class TestCovariance {
public static void main(String[] args) {
Child c = new Child();
Parent p = new Child();
Integer i1 = c.getSomething(); //this is ok
Integer i2 = p.getSomething(); //this one gives a runtime exception
}
}
As you see in the comment of that line that gives a runtime exception, exception details:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - incompatible types: java.lang.Object cannot be converted to java.lang.Integer
Why does it see the method of c
object returns an Integer
while the method of p
object returns an Object
??
First, I'd like to re-iterate that covariant return types is the ability to change the return type of the overriding method to a subtype of the overridden methods return type which in your case seems correct.
The call to Integer i1 = c.getSomething();
compiles successfully because the receiver type is of Child
and the compiler knows that the return type of c.getSomething()
is Integer
.
However on the other hand, due to the fact that you're using Parent
as the receiver type of p
, only the methods of the Parent
class are visible through this reference even if the actual object p
is referring to is a Child
and obviously p.getSomething()
is assumed to return Object
at compile time and you're attempting to assign it to an Integer
, hence the compilation error.
Having said that the call Integer i2 = p.getSomething();
could succeed at runtime but as mentioned it's a compile-time error as the compiler checks and ensures that you only invoke methods that exist for the receiver type.
Also as mentioned by davidxxx:
the RuntimeException is thrown but it is not thrown by the program itself but the IDE as it "discovers" that the started program has a uncompilable class.