I know the behavior, but I am not 100% sure on why this occurs.
I understand that there is no polymorphism for instance variables in java. The variables are resolved statically by the compiler.
But in the following I am confused on something:
class Animal{
String name = "Animal";
public void display(){
System.out.println("My name is "+ name);
}
}
public class Dog extends Animal {
String name = "Dog";
public static void main(String[] args) {
Animal a = new Dog();
Dog d = new Dog();
System.out.println(a.name);//Line 1
a.display();//Line 2
d.display();//Line 3
}
}
I undertand that in Line 1
it will display Animal
as it is the static type of a
(resolved by compiler).
What confuses me is why Line 3
will also display My name is Animal
?
The method will be tried to be called on Dog
since this is the actual object at runtime and since it is not overidden the method will be found in the parent class Animal
.
What I don't get is why the name
of the parent class is used inside the method display
if the actual object operated on is a Dog
. Doesn't it hide the parent's name
variable? It does not seem to me like it is statically resolved since the type is Dog
.
Isn't it part of the oject's memory layout?
It is like inside display
only the parent's variable is visible. Why?
Update:
The answers by @Razvan and @LouisWasserman have been helpful.
I have 1 last question after these:
The point from both seems to be the following:
From @RazyanSystem.out.println("My name is "+ this.name); //<-- note the this
From @Louis
That the this
refers to Animal
and that the implementation of display() is in the Animal class
.
So far ok. But how are these points consistent with the fact that if I modify display()
as follows:
class Animal{
String name = "Animal";
public void display(){
System.out.println("Current class is "+ this.getClass().getName());
System.out.println("My name is "+ name);
}
}
Then the result of:
Dog d = new Dog();
d.display();
Current class is Dog
My name is animal
I was expecting that this
inside the display
would be Animal
as I understood the answers here. But it is not. Why?
When you invoke d.display()
the Animal.display()
is called, since you don't override it in the Dog class.
So an imaginary implementation of Dog.display()
would be something like:
public void display(){
super.display();
}
And the implementation of Animal.display() is:
public void display(){
System.out.println("My name is "+ this.name); //<-- note the this
}
The Animal.display()
method is not even aware of the existence of an object Dog
and consequently of its name
variable
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