Marian Paździoch
Marian Paździoch

Reputation: 9113

Why method from sub class is called when invoked from super class?

My code looks like this:

public abstract class BaseClass{
  public void update() {
      //...
  }

  public void somethingHappenedSoCallUpdate() {
      update();
  }
}

public class ExtendingClass extends BaseClass{
  @Override
  public void update() {
      //...
  }
}

There's an instance of ExtendingClass and at some point method somethingHappenedSoCallUpdate() is called. And I expect the method will call BaseClass.update() but ExtendingClass.update() is called. Can someone explain why?

Upvotes: 1

Views: 64

Answers (5)

T.J. Crowder
T.J. Crowder

Reputation: 1075755

And I expect the method will call BaseClass.update() but ExtendingClass.update() is called. Can someone explain why?

Because that's how Java is defined. By default, all non-private methods are virtual, which means that when you have overridden methods, the method that gets called on an instance is the instance's most-overridden version (ExtendingClass's, in your case), regardless of the type reference through which the method call is made. This is fundamental to polymorphism in modern OOP languages.

The compile-time type reference tells the compiler whether code has access to the method; the runtime type of the object tells the JVM which override of the method to call.

Let's take a simple example:

class Base {
    public void method1() {
        System.out.println("Base#method1");
    }
}
class Derived extends Base {
    @Override
    public void method1() {
        System.out.println("Derived#method1");
    }

    public void method2() {
        System.out.println("Derived#method1");
    }
}

// Usage:
Base b = new Derived();
b.method1(); // Calls Derived#method1, the most-overridden version the
             // actual object has
b.method2(); // Fails to compile; Base doesn't define method2, so the
             // code doesn't have access to call it when using a Base
             // reference, even though the object does have the method

Upvotes: 1

Albert Rannetsperger
Albert Rannetsperger

Reputation: 944

You overrode the method so if you still want the code in the abstract class to run you need to implicitly call update() within the overridden method. So...

public class ExtendingClass extends BaseClass {

  @Override
  public void update() {

      super.update(); // Call the base method.
  }
}

Hope that helps :)

Upvotes: 0

Filipp Voronov
Filipp Voronov

Reputation: 4197

Because you overrode update in subclass and since java methods are virtual overridden version is called.

Option #1

Override update, override somethingHappenedSoCallUpdate() method and use there super.update() instead of update().

Option #2

Make update private in superclass:

private void update() 

Upvotes: 0

obsilp
obsilp

Reputation: 396

As @hyde said, Java methods are virtual, thats means that the VM decides at runtime which method to invoke. If you call somethingHappenedSoCallUpdate() on an instance that extends BaseClass then BaseClass.somethingHappenedSoCallUpdate() will be called, but since ExtendingClass is overriding BaseClass.update() it will class ExtendingClass.update() instead of BaseClass.update().

When extending a method you have to think of it like this: whenever you extend a method you put it on a stack and when you invoke it, Java will look on this "stack" and invokes the topmost. That means if you have a BaseClass that has a update() method, this class can be extended by X classes not overriding the update() method but if the X+1 class does, Java will always call that method of X+1.

Upvotes: 0

Safa KH
Safa KH

Reputation: 31

It's polymorphism:the right method is called at runtime depending on the real type of the object it's a dynamic binding.

Upvotes: 0

Related Questions