Java – Using Super Keyword to Access Super Class Members

classinheritancejava

I have following questions about the super keyword in java:

I have a code below with classes:

  • A Extends no class contains integer variable i
  • B Extends class A contains integer variable i
  • C Extends class B contains integer variable i

     class A {
        int i = 20;
    
        A() {
            System.out.println("I am in constructor of the parent class");
        }
    }
    
    class B extends A {
        int i = 30;
    
        B() {
            System.out.println("I am in constructor of the subclass");
        }
    }
    
    class C extends B {
        int i = 40;
    
        C() {
            System.out.println("I am in constructor of the main class");
        }
    
        void display() {
            System.out.println(i);
            System.out.println(super.i);
            /*
             * My first thoughts to access the third variable 'i'
             * inherited indirectly to this class by 'class A'.
             * I thought that it would print 20 :(.
               System.out.println(super.super.i);
             */ 
        }
    
        public static void main(String[] argue) {
            C obj2 = new C(); 
            obj2.display();
        }
    }
    
    1. Now as class B inherits class A so it must have two integer variables i. Class C inherits class B so it will have two integer variables from B and one defined in itself.

Now I can print the inherited super class variable i in class C through the display method and of course the variable i defined in class C itself. The question is how to print the third i which has the value "20".

I know I can define a method in the class B that returns super.i; and call it through its object in class A that will print the third variable i and I also known that I can create an object of class A, but is there any other way by using super or any other thing to directly access the third variable in the class C.

Also the output is:

      I am in constructor of the parent class
      I am in constructor of the subclass
      I am in constructor of the main class
      40
      30
  1. why like the this keyword the super keyword cannot be used inside static methods?

  2. why is the super class constructor called to initialize the inherited variables of a subclass? This doesn't make any sense because if a class extends another class the variables and methods will be like they were locally declared in the class in other words its own members. So why can't the constructor of the subclass initialize those inherited members and has to call the super class constructor to initialize them.

Best Answer

In addition to all the above, consider the following scenario:

  • You start out with these two classes.

     class A {
        int i = 20;
    
        A() {
            System.out.println("I am in constructor of the parent class");
        }
    }
    
    class B extends A {
        int i = 30;
    
        B() {
            System.out.println("I am in constructor of the subclass");
        }
    }
    
  • You compile both classes, it creates two class files: A.class and B.class

  • Now you change your mind and rewrite A:

     class A {
        int i = 10;
    
        A() {
            System.out.println("I am in constructor of the parent class");
        }
    }
    
  • You recompile A, so you get a new A.class, which you replace the old A.class with

Now the question is: how would B know that As initialisation code has changed? You haven't recompiled B, nor should you be required to do so. After all, B may already be packaged up in a different jar, maybe even in a different product you have no control over.*

The only reasonable way to support this case is for Bs constructor to start with calling As constructor and let A initialise itself.

*This may sound far-fetched at first, but this is exactly what happens when internal implementation details of JDK classes are changed. All the previously compiled Java applications in the world should run seamlessly with the new JDK.