Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Calling a super method which calls an overridden method

public class SuperClass {     public void method1()     {         System.out.println("superclass method1");         this.method2();     }      public void method2()     {         System.out.println("superclass method2");     }  }  public class SubClass extends SuperClass {     @Override     public void method1()     {         System.out.println("subclass method1");         super.method1();     }      @Override     public void method2()     {         System.out.println("subclass method2");     } }    public class Demo  {     public static void main(String[] args)      {         SubClass mSubClass = new SubClass();         mSubClass.method1();     } } 

my expected output:

subclass method1
superclass method1
superclass method2

actual output:

subclass method1
superclass method1
subclass method2

I know technically I have overriden a public method, but I figured that because I was calling the super, any calls within the super would stay in the super, this isn't happening. Any ideas as to how I can make it happen?

like image 614
jsonfry Avatar asked Jan 04 '11 15:01

jsonfry


People also ask

How do you call a superclass version of an overridden method?

Invoking overridden method from sub-class : We can call parent class method in overriding method using super keyword. Overriding and constructor : We can not override constructor as parent and child class can never have constructor with same name(Constructor name must always be same as Class name).

Can override method call super?

A subclass can override methods of its superclass, substituting its own implementation of the method for the superclass's implementation.

Can we override Super method in Java?

If a method cannot be inherited, then it cannot be overridden. A subclass within the same package as the instance's superclass can override any superclass method that is not declared private or final. A subclass in a different package can only override the non-final methods declared public or protected.

When an overridden method is called from within a subclass?

When an overridden method is called from within a subclass, it will always refer to the version of that method defined by the subclass. The version of the method defined by the superclass will be hidden.


2 Answers

The keyword super doesn't "stick". Every method call is handled individually, so even if you got to SuperClass.method1() by calling super, that doesn't influence any other method call that you might make in the future.

That means there is no direct way to call SuperClass.method2() from SuperClass.method1() without going though SubClass.method2() unless you're working with an actual instance of SuperClass.

You can't even achieve the desired effect using Reflection (see the documentation of java.lang.reflect.Method.invoke(Object, Object...)).

[EDIT] There still seems to be some confusion. Let me try a different explanation.

When you invoke foo(), you actually invoke this.foo(). Java simply lets you omit the this. In the example in the question, the type of this is SubClass.

So when Java executes the code in SuperClass.method1(), it eventually arrives at this.method2();

Using super doesn't change the instance pointed to by this. So the call goes to SubClass.method2() since this is of type SubClass.

Maybe it's easier to understand when you imagine that Java passes this as a hidden first parameter:

public class SuperClass {     public void method1(SuperClass this)     {         System.out.println("superclass method1");         this.method2(this); // <--- this == mSubClass     }      public void method2(SuperClass this)     {         System.out.println("superclass method2");     }  }  public class SubClass extends SuperClass {     @Override     public void method1(SubClass this)     {         System.out.println("subclass method1");         super.method1(this);     }      @Override     public void method2(SubClass this)     {         System.out.println("subclass method2");     } }    public class Demo  {     public static void main(String[] args)      {         SubClass mSubClass = new SubClass();         mSubClass.method1(mSubClass);     } } 

If you follow the call stack, you can see that this never changes, it's always the instance created in main().

like image 101
Aaron Digulla Avatar answered Sep 22 '22 08:09

Aaron Digulla


You can only access overridden methods in the overriding methods (or in other methods of the overriding class).

So: either don't override method2() or call super.method2() inside the overridden version.

like image 30
Sean Patrick Floyd Avatar answered Sep 24 '22 08:09

Sean Patrick Floyd