Why Instance Variable Of Super Class Is Not Overridden In Sub Class
Tags: java, polymorphism
Published: 2019-06-30 08:38:09

When we create a variable in both parent and child class with the same name, and try to access it using parent's class reference which is holding a child class's object then what do we get?  
  
In order to understand this, let us consider below example where we declare a variable `x` with the same name in both `Parent` and `Child` classes.  
  

    class Parent {
        // Declaring instance variable by name `x`
        String x = "Parent`s Instance Variable";
    
        public void print() {
            System.out.println(x);
        }
    }
    
    class Child extends Parent {
    
        // Hiding Parent class's variable `x` by defining a variable in the child class with the same name.
        String x = "Child`s Instance Variable";
    
        @Override
        public void print() {
            System.out.print(x);
    
            // If we still want to access variable from super class, we do that by using `super.x`
            System.out.print(", " + super.x + "\n");
        }
    }
    

  
  
And now if we try to access `x` using below code, what `System.out.println(parent.x)` will print  
  
  

    Parent parent = new Child();
    System.out.println(parent.x) // Output -- Parent`s Instance Variable
    

  
  
Well generally, we will say `Child` class will override the variable declared in the `Parent` class and `parent.x` will give us whatever `Child's` object is holding. Because it is the same thing which happens while we do the same kind of operation on methods.  
  
But actually it is not, and `parent.x` will give us value Parent\`s Instance Variable which is declared in `Parent` class but why?

  
  
Because variables in Java do not follow polymorphism and overriding is only applicable to methods but not to variables. And when an instance variable in a child class has the same name as an instance variable in a parent class, then the instance variable is chosen from the reference type.  
  
In Java, when we define a variable in Child class with a name which we have already used to define a variable in the Parent class, Child class's variable hides parent's variable, even if their types are different. And this concept is known as **Variable Hiding.**  
  
In other words, when the child and parent class both have a variable with the same name, Child class's variable hides the parent class's variable. You can read more on variable hiding in the article [What is Variable Shadowing and Hiding in Java](https://programmingmitra.com/2018/02/what-is-variable-shadowing-and-hiding.html).  
  

Variable Hiding is not the same as Method Overriding
----------------------------------------------------

While variable hiding looks like overriding a variable similar to method overriding but it is not, overriding is applicable only to methods while hiding is applicable to variables.  
  
In the case of **method overriding**, overriding methods completely replaces the inherited methods so when we try to access the method from parent's reference by holding child's object, the method from child class gets called. You can read more about overriding and how overridden methods completely replace the inherited methods on [Everything About Method Overloading Vs Method Overriding](https://programmingmitra.com/2017/05/everything-about-method-overloading-vs-method-overriding.html), [Why We Should Follow Method Overriding Rules](https://programmingmitra.com/2017/12/why-we-should-follow-method-overriding-rules.html).

  
  
But in **variable hiding** child class hides the inherited variables instead of replacing which basically means is that the object of Child class contains both variables but Child's variable hides Parent's variable. so when we try to access the variable from within Child class, it will be accessed from the child class.  
  
And if I simplify section [Example 8.3.1.1-3. Hiding of Instance Variables](http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#d5e10238) of [Java language specification](http://docs.oracle.com/javase/specs/jls/se7/html/index.html):  
  

> When we declare a variable in a `Child` class which has the same name e.g. `x` as an instance variable in a `Parent` class then  
> 
> 1.  Child class's object contains both variables (one inherited from `Parent` class and other declared in `Child` itself) but the child class variable hides the parent class's variable.
> 2.  Because the declaration of `x` in class `Child` hides the definition of `x` in class `Parent`, within the declaration of class `Child`, the simple name `x` always refers to the field declared within class `Child`. And if the code in methods of `Child` class wants to refer to the variable `x` of `Parent` class then this can be done as `super.x`.
> 
> 4.  If we are trying to access the variable outside of `Parent` and `Child` class, then the instance variable is chosen from the reference type. Thus, the expression `parent2.x` in the following code gives the variable value which belongs to parent class even if it is holding the object of the `Child` but `((Child) parent2).x` accesses the value from the `Child` class because we cast the same reference to `Child`.

  

[![Why Instance Variable Of Super Class Is Not Overridden In Sub Class due to variable shadowing](https://2.bp.blogspot.com/-ri37eZ4bbVk/W-WFc9in3sI/AAAAAAAAR9I/brSieunxW483qLpJU9dWPVo-q5SuBsupQCK4BGAYYCw/s1600/variable-shadowing.jpeg "Why Instance Variable Of Super Class Is Not Overridden In Sub Class due to variable shadowing")](//2.bp.blogspot.com/-ri37eZ4bbVk/W-WFc9in3sI/AAAAAAAAR9I/brSieunxW483qLpJU9dWPVo-q5SuBsupQCK4BGAYYCw/s1600/variable-shadowing.jpeg)

  

Why Variable Hiding Is Designed This Way
----------------------------------------

**So we know that instance variables are chosen from the reference type, not instance type, and polymorphism is not applicable to variables** but the real question is why? why variables are designed to follow hiding instead of overriding.  
  
Because variable overriding might break methods inherited from the parent if we change its type in the child class.

  
  
We know every child class inherits variables and methods (state and behaviour) from its parent class. Imagine if Java allows variable overriding and we change the type of a variable from `int` to `Object` in the child class. It will break any method which is using that variable and because the child has inherited those methods from the parent, the compiler will give errors in `child` class.  
  
For example:  
  

    class Parent {
        int x;
        public int increment() {
            return ++x;
        }
        public int getX() {
            return x;
        }
    }
    
    class Child extends Parent {
        Object x;
        // Child is inherting increment(), getX() from Parent and both methods returns an int 
        // But in child class type of x is Object, so increment(), getX() will fail to compile. 
    }
    

  
If `Child.x` overrides `Parent.x`, how can `increment()` and `getX()` work? In the subclass, these methods will try to return the value of a field of the wrong type!  
  
And as mentioned, if Java allows variable overriding then Child's variable cannot substitute Parent's variable and this would break the Liskov Substitutability Principle (LSP).  
  

Why Instance Variable Is Chosen from Reference Type Instead Of Instance
-----------------------------------------------------------------------

As explained in [How Does JVM Handle Method Overloading and Overriding Internally](https://programmingmitra.com/2017/05/how-does-jvm-handle-method-overriding-internally.html),  at compile time overriding method calls are treated from the reference class only but all overridden methods get replaced by the overriding method at the runtime using a vtable and this phenomenon is called runtime polymorphism.

  

Similarly, at compile time variable access is also treated from the reference type but as we discussed variables do not follow overriding or runtime polymorphism, so they are not replaced by child class variables at the runtime and still refer to the reference type.

  

  
Generally speaking, nobody will ever recommend hiding fields as it makes code difficult to read and creates confusion. This kind of confusion will not there if we always stick to [General Guidelines to create POJOs](https://programmingmitra.com/2016/05/plain-old-java-object-pojo-explained.html) and encapsulate our fields by declaring them as private and provides getters/setters as required so the variables are not visible outside that class and child class cannot access them.  
  
You can find the complete code on this [Github Repository](https://github.com/njnareshjoshi/exercises/blob/master/src/org/programming/mitra/exercises/VariableShadowingExample.java) and please feel free to provide your valuable feedback.