Bogdan
Bogdan

Reputation: 103

Logic behind polymorphism in this example:

class Base {
    public static void staticMethod(Base bObj) {
        System.out.println("In Base.staticMethod()");
        bObj.instanceMethod();
    }
    public void instanceMethod() {
        System.out.println("In Base.instanceMethod()");
    }
}
class Derived extends Base {
    public static void staticMethod(Base bObj) {
        System.out.println("In Derived.staticMethod()");
        bObj.instanceMethod();
    }
    public void instanceMethod() {
        System.out.println("In Derived.instanceMethod()");
    }
}
public class Main {
    public static void main(String []args) {
        Base bObj = new Derived();
        bObj.staticMethod(bObj);
    }
}

Initially, when I saw this example I was sure that the result would be:

"In Base.staticMethod()"
"In Base.instanceMethod()".

After the initialization of the first Derived object it is obvious that it will be interpreted as a Base object due to upcast and it will call the static method of the base class which it does but later when it calls the other method(instance method) it goes inside the derived function instead of base class.

Why, considering that initially it was considered being Base?

Upvotes: 1

Views: 73

Answers (3)

Ralf Kleberhoff
Ralf Kleberhoff

Reputation: 7290

TL;DR:

bObj.staticMethod(bObj); only looks at the compile-time type of bObj, and is equivalent to Base.staticMethod(bObj); in your case. There's no overriding.

bObj.instanceMethod(); only looks at the runtime class of bObj, and selects the method based on that class. So overriding works here.

Explanation

If you call a static method, you should do so by naming the class, not an instance. So bObj.staticMethod(bObj) should better be written Base.staticMethod(bObj). Typically, the compiler will issue a warning for the first version.

That's because the runtime instance is irrevant for selecting the static method. The decision is made by the compiler. And that's why we call this method type "static", because it lacks the dynamic method lookup of instance methods. That means that there is no overriding based on the instance "before the dot".

Using an instance expression misleads the reader into thinking the instance were relevant, and therefore should not be used. And inside the static method, there is no way to refer to the instance "before the dot". The keyword this doesn't exist in static methods. To call a static method, you don't even need an instance of that class (e.g. you can't create Math instances, but you can call Math.min() without any problem).

On the other hand, if you call an instance method, you need an instance of a class having that method, and this instance gets the name this inside the method. The method selection is done at runtime, based on the runtime class of the instance, no matter what the declared type is.

Upvotes: 0

Ramesh Karna
Ramesh Karna

Reputation: 816

Override is only for instance methods. For Static Method the term is called Method Hiding See Detail.
1. If method hiding is used then BaseClass's method is hidden from Subclass. method selection solely depends on which class's reference you are using to call the method. In your example since you are using BaseClass (even you assign Subclass object, it still on the class level it's BaseClass) reference to make a call to the static method it makes a call to BaseClass's method. If you would use SubClass reference as below then it would call the SubClass's static method

public static void main(String []) {
   Derived bObj = new Derived();
   bObj.staticMethod(bObj); 
}
  1. As the call inside the static method is for an Instance method. It uses polymorphism here and calls the SubClass's method.

Upvotes: 0

Eran
Eran

Reputation: 393771

There is no method overriding for static methods. Therefore bObj.staticMethod(), which is equivalent to Base.staticMethod, invokes the static method of the base class.

Inside the static method you are calling bObj.instanceMethod(). For instance methods there is method overriding, and the runtime type of bObj determines which method is executed - the instance method of Derived in your case.

Upvotes: 1

Related Questions