3

I have a super class:

public class SuperClass {

    public void dosomething() {
        firstMethod();
        secondMethod();
    }

    public void firstMethod() {
        System.out.println("Super first method");
    }

    public void secondMethod() {
        System.out.println("Super second method");
    }
}

A sub class:

public class SubClass extends SuperClass {

    public void dosomething() {
        super.dosomething();
    }

    public void firstMethod() {
        System.out.println("Sub first method");
    }

    public void secondMethod() {
        System.out.println("Sub second method");
    }
}

A test class:

public static void main(String[] args) {
      SubClass sub = new SubClass();
      sub.dosomething();
      SuperClass sup = new SuperClass();
      sup.dosomething()
}

when I run the test method, I got this:

Sub first method
Sub second method

Can you tell me how this happened? In the sub class dosomething method, I called super.dosomething() and I think the super method will be called, but the override method in sub class was called.

if I do this:
SuperClass superClass = new SuperClass();
superClass.dosomething();


the result is:
Super first method
Super second method

The difference is method invocation place. I think there must be something I don`t know ):

oops!the super reference pointed to subclass in the first example...

like this:

SuperClass sub = new SubClass();
sub.firstMethod();
sub.secondMethod();

Felix
  • 1,253
  • 7
  • 22
  • 41

4 Answers4

3

In java, the methods binding is always dynamic [ignoring static and private methods here]. Thus, when you override firstMethod() and secondMethod(), any time an object of type SubClass will try to invoke one of them - the overriden method will be invoked - even if it [the invokation] is from the parent's method.

So, as expected - when you invoke super.doSomething(), it calls firstMethod() and secondMethod(), and the overriden methods are being called.

amit
  • 175,853
  • 27
  • 231
  • 333
1

Super.dosomething() does in fact call the method dosomething() in Super class. But inside this method, you call 2 functions which are firstMethod and secondMethod. These methods are overwritten in the Sub class and they are being called from the Sub Class.

As Petar Ivanov suggested:

You can prevent them from being overriden if you mark them final

Adel Boutros
  • 10,205
  • 7
  • 55
  • 89
1

Indeed the super doSomething gets called. Do something calls firstMethod and secondMethod, which are virtual methods (any method in Java is by default virtual, which means it can be overriden). So their overriden versions gets called.

You can prevent them from being overriden if you mark them final.

Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
1

Your object on which the methods are invoked is of type SubClass, not SuperClass. Even if you call a method that is only defined in SuperClass, your execution context remains SubClass. So any method that is invoked that is overridden will in fact execute the overridden method.

The thing to take away from this is that by declaring firstMethod and secondMethod as public, SuperClass is in fact allowing subclasses to override their behaviour. If this is not appropriate, the methods should be private, or final.

Joeri Hendrickx
  • 16,947
  • 4
  • 41
  • 53
  • I think this feature is very useful, but I just don't know how it works in detail :( – Felix Feb 15 '12 at 10:12
  • 2
    @Felix: what don't you understand about it? it's the runtime type of your object that matters, not the type the variable was defined in. – Joeri Hendrickx Feb 15 '12 at 14:01