Search code examples
javainheritanceradixderived-class

Superclass and subclass resolution?


I am new to java programming and very new to stackoverflow too.Came across this simple code which I failed to understand.Please help me how this works

class Base {
 public static void foo(Base bObj) {
 System.out.println("In Base.foo()");
 if(bObj instanceof Base){
     System.out.println("Base instance");
 }
 bObj.bar();
 }

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

Now here i get

In Base.foo()
Base instance
In Derived.bar()

Though I got how it goes base.foo().But how derived.It also prints that it is an instance of a base object then how derived.The explanation given was that earlier it did static resolution and later dynamic.What is static and dynamic resolution.

I though the concept goes as

Base b=new Derived();

This means we create a derived object which is then upcasted to Base.So why not it calls base.bar()?

Thanks in advance.


Solution

  • That's the core of what polymorphism is all about. Objects in Java try to behave the same way as real objects.

    Bikes usually have 3 gears.

    Competion bikes are bikes. But they have 18 gears.

    If I show you a competition bike and ask you "Is it a bike", the answer is yes, right. But if I ask you "How many gears does this bike have", you'll answer "18", because although it's a bike, it's a specialized type of bike which doesn't have 3 gears as common bikes, but 18.

    It's the same with Java objects:

    Base bObj = new Derived();
    

    is the same as

    Bike bike = new CompetitionBike();
    

    I.e. you're constructing a bike, and the concrete type of the bike is "competition bike". So, if you ask the bike how many gears it has, the answer will be 18:

    bike.getGears(); // 18
    

    Similarly,

    bObj.bar();
    

    will invoke the bar() method that is defined in the concrete type of the object, which is Derived. So "In Derived.bar()" will be printed.

    Static methods don't follow these rules, because static methods are not invoked on objects, but on classes.

    Calling bObj.foo(bObj) is legal, but is extremely bad practice. What you should call is either Base.foo()or Derived.foo(), depending on which method you want to call. And the method defined on the given class will be called. When you do the wrong thing and call bObj.foo(), the compiler actually translates bObj to the declared type of bObj, which is Base.