问题
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);
}
}
回答1:
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
.
回答2:
@kris979 Though you are returning B, i think what makes the difference is that the return type is of A. Hence value of x in A i.e. 1 is printed.
回答3:
As Bozho pointed out - instance variable are never affected by polymorphism. Let me give you a quick small example.
class Base {
int i = 1;
void method() {
System.out.println("in base");
}
}
class Sub extends Base {
int i = 2;
void method() {
System.out.println("in sub");
}
}
public class Test {
public static void main(String[] args) {
Base obj = new Sub();
obj.method();
System.out.println(obj.i);
}
}
This code will print - in sub and 1
来源:https://stackoverflow.com/questions/6137189/java-covariant-return-type