Please can someone explain to me how the last 6 lines of the output get printed. I know that due to static binding the first three lines are printed appropriately.
I do not know why the 5th line gives the output because it is of type Ipod and it does not have any method for song but still it prints the output. Here is the code:
package myferrari;
import mycar.*;
class IPOD
{
void PlayMusic(Music m)
{
System.out.println("Music from Ipod");
}
}
class IpodPlayer extends IPOD
{
void PlayMusic(Music m)
{
System.out.println("Music from IpodPlayer");
}
void PlayMusic(Song m)
{
System.out.println("Song from IpodPlayer");
}
}
class Music{}
class Song extends Music{}
public class Main {
public static void main(String [] args)
{
IPOD ipod = new IPOD();
IpodPlayer iplayer = new IpodPlayer();
IPOD ipl = new IpodPlayer();
Music m = new Music();
Song s = new Song();
Music sm = new Song();
iplayer.PlayMusic(m);
iplayer.PlayMusic(s);
iplayer.PlayMusic(sm); // static binding refers to the reference type
ipod.PlayMusic(m);
ipod.PlayMusic(s);
ipod.PlayMusic(sm);
ipl.PlayMusic(m);
ipl.PlayMusic(s);
ipl.PlayMusic(sm);
}
}
The output is here:
Music from IpodPlayer
Song from IpodPlayer
Music from IpodPlayer
Music from Ipod
Music from Ipod
Music from Ipod
Music from IpodPlayer
Music from IpodPlayer
Music from IpodPlayer
Nut shell: Whole concept is about method overloading and overriding and how they are linked with dynamic and static binding.
Now, first of all see below snippet which is simplification of your case @run-time and understand the run-time picture. Debug your code using any IDE of your choice and you will see exactly same result.
Major take-away: At run-time your reference will resolve to the actual object, this is called as Dynamic binding or polymorphism. Run-time means object. So, whether
IpodPlayer iplayer = new IpodPlayer();
ORIPOD ipl = new IpodPlayer();
, at run-time you will get instance ofIpodPlayer
and its method would be called.Dynamic binding in linked with method overriding. So, at run-time which overridden method will be called is decided by checking the object type. So, you can see that whatever be the reference type, at run-time
PlayMusic
method of actual object is called.This sums up your dynamic binding and method overriding.
Coming to static binding and method overloading.
Static binding clear things on how overloaded methods in java are bonded during compile time using Type information.
Now, your case of
IPOD ipod = new IPOD();
is very clear, since you have only method and no overloaded method so your result no. 4,5 and 6 are self explanatory.Real confusion is in case of
IpodPlayer iplayer = new IpodPlayer();
ANDIPOD ipl = new IpodPlayer();
.At compile time it is decided that which overload method will be called based on object type, whether
PlayMusic(Music m)
orPlayMusic(Song m)
. Please note, I am talking only about method and not which class or object..Now, in your case no. 1,2 and 3, since the object the of
new IpodPlayer()
and you have two overloaded method so appropriatePlayMusic
method is called, based on object type ofPlayMusic
Last cases - your case no. 7, 8 and 9 which is major head scratching cases and most important to understand because it combines concept of dynamic binding as well as static binding.
Again at compile time which overloaded method to be called is decided based on object type but since at compile time it is deciding based on the
IPOD ipl
and not= new IpodPlayer();
, so compiler decides and generates the byte code thatPlayMusic(Music m)
will get called at run-time (which ever object's method butPlayMusic(Music m)
method) becauseIPOD
doesn't have any other method. And finally at run-time dynamic binding will come into picture and method ofIpodPlayer
will be called because of= new IpodPlayer();