问题
class A {
int i = 1;
int f() { return i; }
}
class B extends A {
int i = 2;
int @Override f() { return -i; }
}
public class override_test {
public static void main(String args[]) {
B b = new B();
A a = (A) b; // Cast b to an instance of class A.
System.out.println(a.i); // Now refers to A.i; prints 1;
System.out.println(a.f()); // Still refers to B.f(); prints -2;
}
}
I am wondering why a.f() still refers to B.f() while a.i refers to A.i.
thanks in advance!
回答1:
Simple rule is when you call a method, it will be on instance type (polymorphism) in this case instance is of type B
even though reference is of type A
.
When you call variable, it will be on Type of the reference.
Read more about Ploymorphism
回答2:
In java fields are not polymorphic that's why a.i
refers to A.i
While a.f()
refers to B.f()
because b
is an object ob B
, though you are casting it to A
it means that you will be able to use only those methods that are declared in A
.
But the object is still of type B
.
So when you access a field it's based on reference type and when you access method it's based on object type
回答3:
That's just the way it is. Java instance method calls are, in C++ terms, virtual. The method chosen depends on the actual class of the target object, rather than the type of the reference to it. Field references are not virtual, and the choice of field depends on the type of the reference.
I generally keep fields private or protected, and work through methods rather than direct external access to fields
来源:https://stackoverflow.com/questions/14912847/interesting-behavior-of-calling-method-after-casting-a-subclass-to-a-super-class