Learner
Learner

Reputation: 21425

Access a variable using parent reference type in java

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

Answers (4)

Zabi
Zabi

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

AnkeyNigam
AnkeyNigam

Reputation: 2820

Just Keep the Thumb Rule as :

  1. In case of Method Overriding the reference variable does not matter but what matters is the actual object type which this variable is referring to.
  2. In case of Variable Shadowing the reference variable matters while the actual object type which this variable is referring to, does not matter.

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

Itay Maman
Itay Maman

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

Eran
Eran

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

Related Questions