Why does below code prints "1" ?
class A {
int x = 1;
}
class B extends A {
int x = 2;
}
class Base {
A getObject() {
System.out.println("Base");
return new B();
}
}
public class CovariantReturn extends Base {
B getObject() {
System.out.println("CovariantReturn");
return new B();
}
/**
* @param args
*/
public static void main(String[] args) {
Base test = new CovariantReturn();
System.out.println(test.getObject() instanceof B);
System.out.println(test.getObject().x);
}
}
In object-oriented programming, a covariant return type of a method is one that can be replaced by a "narrower" type when the method is overridden in a subclass. A notable language in which this is a fairly common paradigm is C++.
Java allows for Covariant Return Types, which means you can vary your return type as long you are returning a subclass of your specified return type. Method Overriding allows a subclass to override the behavior of an existing superclass method and specify a return type that is some subclass of the original return type.
The covariant return typeA primitive type like int , float , reference , or void type can be the return value. As we said earlier, covariant return type means that a method's return type can be replaced with a narrower one when overridden in a subclass or child class.
1) Covariant return type assists to stay away from the confusing type casts in the class hierarchy and makes the code more usable, readable, and maintainable. 2) In the method overriding, the covariant return type provides the liberty to have more to the point return types.
Because you are referring to fields, which are not affected by polymorphism. If you instead used getX()
, it would've returned 2
.
What you are asking is, the value of field x
defined in class A
(because Base.getObject()
returns A
). Even though CovariantReturn
overrides the method to return B
, you are not referring to your object as CovariantReturn
.
To expand a bit on how fields are not affected by polymorphism - field access is realized at compile time, so whatever the compiler sees, that's what's accessed. In your case the method defines to return A
and so A.x
is accessed. On the other hands methods are invoked based on the runtime type. So even if you define to return A
but return an instance of B
, the method you invoke will be invoked on B
.
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