Calling super super class method

38,358

Solution 1

You can't even use reflection. Something like

Class superSuperClass = this.getClass().getSuperclass().getSuperclass();
superSuperClass.getMethod("foo").invoke(this);

would lead to an InvocationTargetException, because even if you call the foo-Method on the superSuperClass, it will still use C.foo() when you specify "this" in invoke. This is a consequence from the fact that all Java methods are virtual methods.

It seems you need help from the B class (e.g. by defining a superFoo(){ super.foo(); } method).

That said, it looks like a design problem if you try something like this, so it would be helpful to give us some background: Why you need to do this?

Solution 2

You can't - because it would break encapsulation.

You're able to call your superclass's method because it's assumed that you know what breaks encapsulation in your own class, and avoid that... but you don't know what rules your superclass is enforcing - so you can't just bypass an implementation there.

Solution 3

You can't do it in a simple manner.

This is what I think you can do:

Have a bool in your class B. Now you must call B's foo from C like [super foo] but before doing this set the bool to true. Now in B's foo check if the bool is true then do not execute any steps in that and just call A's foo.

Hope this helps.

Solution 4

Yes you can do it. This is a hack. Try not to design your program like this.

class A
{
    public void method()
    { /* Code specific to A */ }
}

class B extends A
{
    @Override
    public void method()
    { 
       //compares if the calling object is of type C, if yes push the call to the A's method.
       if(this.getClass().getName().compareTo("C")==0)
       { 
           super.method(); 
       }
       else{  /*Code specific to B*/  }

    }
}

class C extends B
{
    @Override
    public void method()
    { 
        /* I want to use the code specific to A without using B */ 
        super.method();

    }
}

Solution 5

To quote a previous answer "You can't - because it would break encapsulation." to which I would like to add that:

However there is a corner case where you can,namely if the method is static (public or protected). You can not overwrite the static method.

Having a public static method is trivial to prove that you can indeed do this.

For protected however, you need from inside one of your methods to perform a cast to any superclass in the inheritance path and that superclass method would be called.

This is the corner case I am exploring in my answer:

public class A {
    static protected callMe(){
        System.out.println("A");
    }
}

public class B extends A {
    static protected callMe(){
        System.out.println("B");
    }
}

public class C extends B {
    static protected callMe(){
        System.out.println("C");
        C.callMe();
    }

    public void accessMyParents(){
        A a = (A) this;
        a.callMe(); //calling beyond super class
    }
}

The answer remains still No, but just wanted to show a case where you can, although it probably wouldn't make any sense and is just an exercise.

Share:
38,358
Harish
Author by

Harish

Updated on July 09, 2022

Comments

  • Harish
    Harish almost 2 years

    Let's say I have three classes A, B and C.

    • B extends A
    • C extends B

    All have a public void foo() method defined.

    Now from C's foo() method I want to invoke A's foo() method (NOT its parent B's method but the super super class A's method).

    I tried super.super.foo();, but it's invalid syntax. How can I achieve this?

  • Aaron Digulla
    Aaron Digulla almost 14 years
    Odd.. I remember that there was a way to call Object.toString() even if toString() was overloaded by a superclass. But Type.this doesn't compile. :-/
  • Jon Skeet
    Jon Skeet almost 14 years
    @Aaron: I'm not sure about Object.toString() - were you thinking of System.identityHashCode?
  • Aaron Digulla
    Aaron Digulla almost 14 years
    Never used that, I'm pretty sure that it was toString(). Object.super.toString() doesn't work either. Maybe it was a bug in an early Java version or something.
  • Nikita Rybak
    Nikita Rybak almost 14 years
    That's the wildest Java hack ever :)
  • polygenelubricants
    polygenelubricants almost 14 years
    Jon Skeet's answer is best: this kind of functionality should not be enabled because it breaks encapsulation. Instead of addressing the HOW to do something like this, we should address the WHY would anyone even want to do something like this (and tear apart that argument for violating OOP principles).
  • Madhup Singh Yadav
    Madhup Singh Yadav almost 14 years
    @Nikita Rybak: People ask for things that should not be asked. Hence the answers that should not be given ;)
  • Madhup Singh Yadav
    Madhup Singh Yadav almost 14 years
    @polygenelubricants : I am not challenging Skeet's answer. I do not dare too. I just gave my view point.
  • emory
    emory almost 14 years
    It would seem to be thread unsafe. If you are going to do something like this you can put void foo ( boolean flag ) { if ( flag ) super . foo ( ) ; else this . foo ( ) ; } in class B. As for encapsulation, once you come up with some reason why class B should have a foo(boolean) method, then how it is implemented is an implementation detail.
  • Andreas Dolk
    Andreas Dolk almost 14 years
    (I was too much impressed by Aarons now deleted answer that I deleted mine two seconds after posting ;) - undeleted it even though there are much better answers available now)
  • Harish
    Harish over 13 years
    It was not my requirement. I was just thinking out of my head all possibilites of playing around with inheritance and got this question. Thanks.. I got the answer
  • Aboutblank
    Aboutblank about 11 years
    this doesn't actually answer the question. please reread the question.
  • xdevs23
    xdevs23 about 8 years
    Well I need to do that because the super class overrides the super super class in a way I don't want.. and it is a library... so I want to call the one from super super class... maybe taking the source code of the method of the super super class and overriding again solves this?
  • Landei
    Landei about 8 years
    Of course you can write in your method what you want, so in this case copying the code should work. However, if the super-super-class uses private or package private fields or methods in foo(), you need reflection to access these (and of course you are out of luck if a security manager is in place). Further, if the original foo() code makes super calls itself, it wouldn't work either.
  • Prasath Govind
    Prasath Govind over 6 years
    This is called Inversion of Control!