Reputation: 9113
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
Reputation: 1075755
And I expect the method will call
BaseClass.update()
butExtendingClass.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
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
Reputation: 4197
Because you overrode update in subclass and since java methods are virtual overridden version is called.
Override update, override somethingHappenedSoCallUpdate()
method and use there super.update()
instead of update()
.
Make update private in superclass:
private void update()
Upvotes: 0
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
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