Reputation: 2183
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.
Upvotes: 0
Views: 117
Reputation: 14448
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 "
Upvotes: 1
Reputation: 756
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)
Upvotes: 0
Reputation: 10497
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.
Upvotes: 0