0

I want some clear idea about Dynamic Polymorphism. When methods in child class are over-ridden and overloaded, I am unable to figure out method calls.

Here is the Parent class:

Parent Class:

public class Parent {

    void print(Parent parent){
        System.out.println("I am parent classes only print method.");
    }
}

Child Class:

public class Child extends Parent {

    void print(Child child) {
        System.out.println("I am child class' child print method.");
    }


    void print(Parent parent) {
        System.out.println("I am Child class' parent print method ");
    }


}

And this is the caller class.

public class Caller {

    public static void main(String[] args) {

        Parent p = new Parent();
        Child c = new Child();
        Parent pc = new Child();

        p.print(p);
        p.print(c);
        p.print(pc);

        c.print(p);
        c.print(c);
        c.print(pc);

        pc.print(p);
        pc.print(c);
        pc.print(pc);

    }

}

I can see the output in console but cannot understand the reason behind the method calls.

Bhargav Jhaveri
  • 2,123
  • 1
  • 18
  • 23
  • Looks like an odd [Visitor](https://en.wikipedia.org/wiki/Visitor_pattern) to me. – Elliott Frisch Oct 23 '15 at 04:10
  • *"When methods in child class are over-ridden and overloaded, I am unable to figure out method calls."* ... this should never be the case. Overload resolution in Java occurs at compile time, not at run time. If the compiler can tell from your code which method to invoke, then you can too. – scottb Oct 23 '15 at 05:57

3 Answers3

1

The working is simple - overloading is resolved at compile time, and overriding is resolved at runtime (polymorphism).

So, let's see what happens in each of your method calls...

We will ignore calls using Parent p = new Parent(); since it doesn't have overloading or overriding and all the method calls will directly use the parent's single method "I am parent classes only print method.".

Also note that, the compiler cares only about the variable's reference type. And the runtime cares only about the actual object's type.

So, in the statement Parent pc = new Child(), any compile time decision on pc will refer to Parent and any runtime decision on pc will refer to Child.

Here's the logic for the other method calls,

c.print(p);
//Compiler resolves that `print(Parent)` method should be called.
//Runtime resolves that child objects method should be called.
//Prints "I am Child class' parent print method "

c.print(c);
//Compiler resolves that `print(Child)` method should be called.
//Runtime resolves that child objects method should be called.
//Prints "I am Child class' child print method "

c.print(pc);
//Compiler resolves that `print(Parent)` method should be called.
//Runtime resolves that child objects method should be called.
//Prints "I am Child class' parent print method "

pc.print(p);
//Compiler resolves that `print(Parent)` method should be called.
//Runtime resolves that child objects method should be called.
//Prints "I am Child class' parent print method "

pc.print(c); //PAY ATTENTION TO THIS...
//Compiler resolves that `print(Parent)` method should be called.
// This is because PC is Parent type reference and compiler doesn't find `print(Child)` in Parent class, so it uses `print(Parent)`.
//Runtime resolves that child objects method should be called.
//Prints "I am Child class' parent print method "

pc.print(pc);
//Compiler resolves that `print(Parent)` method should be called.
// This is because Compiler knows only about the variable's reference type (And PC is of type Parent). Hence `print(Parent)` would be chosen.
//Runtime resolves that child objects method should be called.
//During runtime, the type of the actual object is used. And PC is referring to an Child object... So `pc.print(...)` will call the child's method.
//Prints "I am Child class' parent print method "
Codebender
  • 14,221
  • 7
  • 48
  • 85
0

This question looks like a duplicate of difference-between-method-overloading-and-overriding

There is a core difference between overriding (polymorphism) and overloading.

Overriding (polymorphism) is determined at runtime. Method overloading is determined at compile time.

The compiler identifies the method to invoke based on the concrete types available.

So for c.print(c); is the only invocation that matches the signature: Child.print(final Child child)

Community
  • 1
  • 1
Tim
  • 726
  • 5
  • 18
  • The basic difference between method overriding and overloading is clear to me. But I wanted clear runtime method choosing scenario. – Bhargav Jhaveri Oct 23 '15 at 05:35
0

Let's consider only two object, one is P(Parent) and second is C(Child). Now P can see only those methods and variables which are accessible to it. In our case it has access to only parent class' print method. So whenever you call print method using parent object, it will call only print method of parent class.

p.print(p);
p.print(c);
p.print(pc);

Means all above line will call print method of parent class as child's method is not accessible to parent.

For an object of child which is assigned to parent like variable pc, it will call overrided method of child class, which is child class' parent method.

pc.print(p);
pc.print(c);
pc.print(pc);

Now for method using child class C, there are two possibilities of method call, one is print method which accepts parent as an argument and second accepts child as an argument. So it all depends on which argument you are passing in method call.

c.print(p);
c.print(c);
c.print(pc);

In first and third call, you are passing parent object as an argument to method, so dynamically compiler identify which method should be invoked as per the passed argument, so child class' parent method will be invoked when parent object is passed as an argument else child class' child method will be invoked.

Vimal Bera
  • 10,346
  • 4
  • 25
  • 47
  • 1
    Your description is wrong. The 3 `pc.` calls will call the child print method due to overriding – Tim Oct 23 '15 at 04:19