Core Java

Why Calling super.super.method() is Not Allowed in Java

Java follows a strict object-oriented approach with a well-defined inheritance model. Unlike some languages that allow direct access to grandparent methods, Java restricts access to only the immediate superclass using super. Let us delve into understanding why Java super super not allowed is a restriction in the language.

1. Understanding the Problem

In Java, the super keyword allows a subclass to access methods of its direct superclass. It allows access to:

  • Superclass methods that are overridden in a subclass.
  • Superclass constructors.
  • Superclass instance variables.

However, developers sometimes expect to call methods of the grandparent class (two levels up) directly using super.super.method(), but Java does not allow this.

2. Why super.super.method() Is Forbidden in Java?

Java enforces encapsulation and method resolution through a single-level inheritance mechanism. Directly calling a grandparent’s method would break this encapsulation and can lead to ambiguity in method resolution.

2.1 Example of the Issue

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
class Grandparent {
    void show() {
        System.out.println("Grandparent method");
    }
}
 
class Parent extends Grandparent {
    void show() {
        System.out.println("Parent method");
    }
}
 
class Child extends Parent {
    void display() {
        // Attempting super.super.show() is NOT ALLOWED
        // super.super.show();  // This will cause a compilation error
    }
}

The above example attempts to call super.super.show() but fails to compile because Java does not allow skipping levels in inheritance.

2.2 Why Java Restricts super.super.method()?

In the above example, Java programming language prevents super.super.method() because:

  • Violation of Encapsulation: Java enforces encapsulation by ensuring that a subclass interacts with its immediate superclass without direct access to deeper levels of the inheritance chain. Allowing super.super.method() would expose internal implementation details of the class hierarchy, making it harder to refactor or modify base classes without affecting subclasses.

    In the following code, class C should only interact with B, but if super.super.method() were allowed, it would break encapsulation and tightly couple C to A, violating abstraction principles.

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    class A {
        void show() {
            System.out.println("Class A method");
        }
    }
     
    class B extends A {
        @Override
        void show() {
            System.out.println("Class B method");
        }
    }
     
    class C extends B {
        @Override
        void show() {
            System.out.println("Class C method");
            super.show(); // Calls B's method
            // super.super.show(); // Invalid in Java - would break encapsulation
        }
    }
     
    public class Main {
        public static void main(String[] args) {
            C obj = new C();
            obj.show();
        }
    }
  • Ambiguity with Multiple Inheritance via Interfaces: While Java does not support multiple inheritance with classes, it allows a class to implement multiple interfaces. If Java permitted super.super.method(), resolving method calls from multiple interfaces could lead to conflicts, especially when different interfaces provide default methods with the same name.

    In the example below, interfaces X and Y both define a show() method. If super.super.show() were allowed, it would be unclear which implementation should be invoked.

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    interface X {
        default void show() {
            System.out.println("Interface X");
        }
    }
     
    interface Y {
        default void show() {
            System.out.println("Interface Y");
        }
    }
     
    class Z implements X, Y {
        @Override
        public void show() {
            // Conflict! Java does not allow automatic resolution of super calls from multiple interfaces.
            // super.super.show(); // Invalid in Java
            X.super.show(); // Must explicitly specify which interface to call
        }
    }
     
    public class Main {
        public static void main(String[] args) {
            Z obj = new Z();
            obj.show(); // Calls X's implementation explicitly
        }
    }
  • Dynamic Method Resolution (Polymorphism) via Virtual Method Table (VMT): Java uses a mechanism called the Virtual Method Table (VMT) to resolve method calls dynamically at runtime. This ensures that the most specific overridden method in the hierarchy is executed. If super.super.method() were allowed, it would bypass this mechanism, leading to unexpected behavior and breaking polymorphism.

    In the example below, Java ensures that method resolution happens dynamically. If super.super.method() were allowed, it would force execution of a grandparent’s method, breaking the expected behavior.

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    class Parent {
        void display() {
            System.out.println("Parent class");
        }
    }
     
    class Child extends Parent {
        @Override
        void display() {
            System.out.println("Child class");
        }
    }
     
    class GrandChild extends Child {
        @Override
        void display() {
            System.out.println("GrandChild class");
            super.display(); // Calls Child's method
            // super.super.display(); // Invalid in Java - would break VMT resolution
        }
    }
     
    public class Main {
        public static void main(String[] args) {
            Parent obj = new GrandChild();
            obj.display(); // Calls the most overridden method in GrandChild due to VMT
        }
    }

3. A Workaround: Indirect Call

Though super.super.method() is not allowed, we can explicitly call the grandparent’s method by defining a public method in the parent class that exposes it.

3.1 Workaround Example

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Base class (Grandparent) with a method 'show'
class Grandparent {
    void show() {
        System.out.println("Grandparent method");
    }
}
 
// Intermediate class (Parent) that overrides 'show' from Grandparent
class Parent extends Grandparent {
    void show() {
        System.out.println("Parent method");
    }
 
    // Method to explicitly call Grandparent's 'show' using 'super'
    void callGrandparentShow() {
        super.show();  // Calls Grandparent's show() method
    }
}
 
// Child class that extends Parent
class Child extends Parent {
    void display() {
        // Indirectly calls Grandparent's show() through Parent's callGrandparentShow()
        callGrandparentShow();
    }
}
 
// Test class with main method
public class Test {
    public static void main(String[] args) {
        Child c = new Child();
        c.display();
    }
}

3.1.1 Code Explanation and Output

In the given Java code, we have a class hierarchy demonstrating method overriding and the use of super to access a grandparent class method.

The Grandparent class has a method show() that prints “Grandparent method”. The Parent class extends Grandparent and overrides the show() method to print “Parent method”. Additionally, it has a method callGrandparentShow(), which explicitly calls the show() method from Grandparent using super.show().

The Child class extends Parent and defines a method display(), which calls callGrandparentShow(). This ensures that the show() method from Grandparent is invoked, bypassing the overridden show() method in Parent.

In the main method, an instance of Child is created, and the display() method is called. This triggers a chain of method calls:display()callGrandparentShow()super.show(), resulting in “Grandparent method” being printed.

1
Grandparent method

This code illustrates the concept of method overriding and how super can be used to access methods from grandparent classes in a multilevel inheritance structure.

4. Conclusion

Java enforces a strict inheritance model where a subclass can access only its immediate superclass using super. This prevents direct calls to grandparent methods using super.super.method(). However, a workaround exists by defining a method in the parent class that explicitly calls the grandparent’s method. Understanding these restrictions helps in designing clean, maintainable, and encapsulated Java applications.

Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button