Reputation: 5492
Example code:
public class Parent {
String name = "Parent";
public String getName() {
return this.name;
}
}
public class Child extends Parent {
String name = "Child";
public String getName() {
return this.name;
}
}
public class Tester {
public static void main (String[] args) {
Parent p = new Child();
Child c = new Child();
System.out.println("p.name is " + p.name); // prints out "Parent"
System.out.println("c.name is " + c.name); // prints out "Child"
System.out.println("p.getName() is " + p.getName()); // prints out "Child"
System.out.println("c.getName() is " + c.getName()); // prints out "Child"
}
}
My Understanding So Far
So far, my understanding of inheritance in Java allows me to understand why the 3rd and 4th println
statements produce "Child" as an output. At compile time, the compiler makes sure that getName
method is defined in the type of the reference variable but during runtime is when which version getName
is determined. And since both reference variables actually refer to a Child
object, Child's getName
is invoked.
Question 1
However, why is it that when you access the instance variable directly, the behavior is different from how methods are accessed? In particular, I find it strange that p.name
returns "Parent" instead of "Child".
Question 2
In a similar vein, if I commented out the getName
function in the Child
class and re-ran the code in Tester
, I'm surprised to see that p.getName()
and c.getName()
return "Parent" instead of "Child".
Can someone help elaborate on these 2 questions?
Upvotes: 3
Views: 107
Reputation: 20760
Variables can not be overridden in Java. What you have done is called hiding a variable (the variable name
in Parent
is difficult to access)
The way to understand the behavior you are describing is to think of name
as only the name of the variable, not an actual variable. When used in the context (in terms of code, not actual type of a variable) of Parent
it points to a different variable than when used in the context of Child
.
When calling c.name
or p.name
you tell the program which context to use, because the variables c
and p
are declared respectively of type Child
and Parent
. When using it in a method inside the class the variable of the current class is used.
If you want to use the Parent.name
in a child class you will have to cast it:
System.out.println("c.name is " + ((Parent) c).name);
For a method, the function called is always that of the actual type of the variable being called. In your case, regardless of calling it from Tester
, Parent
or Client
.
Of course it is best not to hide variables at all, an use different names for different variables.
Upvotes: 4