public class Animal{
int n = 5;
public static void main(String[] args) {
Animal a = new Animal();
Animal ah = new Horse();
Horse h = new Horse();
System.out.println(h.n); // prints 7
System.out.println(ah.n); // prints 5
h = (Horse) ah;
System.out.println(h.n); // prints 7
}
}
class Horse extends Animal{
int n = 7;
}
My question:
Why does h.n still print 7 after h = (Horse) ah? After the assignment it should point to the same object that ah points and the n field points to 5?
First, let's call the field
nof the classAnimal"Animal.n" to avoid confusion.Fields, unlike methods, are not subject to overriding. So in your Horse class, where you may think you are overriding the value of
Animal.nwith 7, you are actually declaring a new variable calledn(let's call itHorse.nto avoid confusion).So really, you have a class called
Horsewith two fields:Animal.nandHorse.n. Which field you get when you say "n" depends upon the static type of the variable at the time.When you have an object whose type is
Horse, but upcast to anAnimal, thenfield refers toAnimal.n, and has a value of "5". Henceah.nis "5".When you have the same object, downcast again to a
Horse, thenfield refers toHorse.n, and has a value of "7". Henceh.nis "7".To clarify: Indeed,
hdoes point to the same object thatahpoints to -- downcasting does not change what object is being pointed at. However, the static type does affect which field of the object is being requested.