Reputation: 21425
I have created 2 classes - Parent
and Child
, both like this:
Parent.java
public class Parent {
String name = "Parent";
}
Child.java
public class Child extends Parent {
String name = "Child";
}
The Child class is shadowing the parent class instance variable name
.
I have created a main program like this:
Test.java
public class Test {
public static void main(String[] args) {
Parent p = new Parent();
Child c = new Child();
System.out.println(p.name);
System.out.println(c.name);
Parent pc = new Child();
System.out.println(pc.name);
}
}
The output of the program is this:
Parent
Child
Parent
Now I am not clear on when I try to access pc.name
then I am getting output as Parent
as per the above output instead of Child
.
My understanding was like this, I created a reference variable pc
of type Parent
but it points to Child
object as er my program. So during run-time time of the program, java creates an object in heap memory for the child class and since the child class is shadowing the name
variable, the output of pc.name
will be Child
. But as per the program my understanding was not correct and this concept applies to only methods that are overriden by child class.
Can you please explain why it is different in the case of instance variable compared to methods?
Upvotes: 4
Views: 4032
Reputation: 1
When u create a Child class object in java, internally the parent class object will also be created which would be referenced by super keyword. Now, using the Parent reference what all you can access from the Child class? Ans. Using the parent reference you can only access the inherited and overridden methods of the Child class. In other words, only the methods can be invoked using the Parent reference. Now the Question is what happens when you use it with the variables/fields - Firstly, Understand how the access to variables is resolved?
Access to variables is always resolved the way static type is resolved (that is: the type of the variable) during the Compile-Time. However the methods which are determined by the runtime type of the actual object. In this program, s.name will be resolved at the COMPILE-TIME itself. That is, s.name will be resolved to Shape.name Obviously the output now has to be Shape.
Upvotes: 0
Reputation: 2820
Just Keep the Thumb Rule as :
Consider the below modified classes of yours :
public class Parent {
String name = "Parent";
public void printName(){
System.out.println("Parent Method");
}
}
public class Child extends Parent {
String name = "Child";
public void printName(){
System.out.println("Child Method");
}
}
Now will run this main()
method in Test Class :-
public class Test {
public static void main(String[] args) {
Parent p = new Parent();
Child c = new Child();
System.out.println(p.name); // will print Parent's name
System.out.println(p.printName());// will call Parent
System.out.println(c.name); // will print Child's name
System.out.println(c.printName());// will call Child
Parent pc = new Child();
System.out.println(pc.name);// will print Parent's name
System.out.println(pc.printName());// will call Child
}
}
This will print the below in Accordance to the rules , which I stated above :-
Parent
Parent Method
Child
Child Method
Parent
Child Method
Upvotes: 2
Reputation: 30733
Access to fields is always determined by the static type (that is: the type of the variable). This is in contrast to methods which are determined (a.k.a "resolved", "bound") by the runtime type of the actual object.
In other words: for field access, the compiler determines, at compilation time, is going to be accessed. In your example, you access pc.name
. The compiler checks the type of the pc
variable, sees that it is of type Parent
and hence generates code that accesses the .name
field of the Parent
class.
Upvotes: 5
Reputation: 393956
There's no overriding for instance variables.
Your Child
class has two name
instance variables. The one in the Child class hides the one in the Parent class (BTW, they don't have to both be of the same type).
When you access name
via a Parent
reference, you get the name
variable of the Parent
class. When you access name
via a Child
reference, you get the name
variable of the Child
class.
Upvotes: 7