Java - Polymorphism
Polymorphism by definition means many forms. Which signifies, an object can exist in different forms.
Story :
An Animal exist in different forms. They are Dog, Cat, Deer e.t.c. So an Animal is not a physical entity but Cat, Dog etc are. So, the Animal creator god had prepared an abstract class called 'Animal'. But why an abstract class?
Because we know, all animals breathes oxygen. So, the breathe() behaviour can be specified. But what about the sound() behaviour? Cats and Dogs don't make the same sound. So, sound() is abstract. Thus the Animal class is abstract.
At the same time Animal creator has to obey the rules of Supreme god by implementing 'LivingBeing' Interface.
LivingBeing Interface
interface LivingBeing{
public abstract void breathe(); // Undefined
public abstract void sound(); // Undefined
}
Animal class
abstract class Animal implements LivingBeing{
public void breathe(){
System.out.println("Breathes Oxygen.");
}
public abstract void sound(); //Undefined so abstract
}
Story :
So, he obeyed the rule made by the Master God. He defined the breathe() behaviour but couldn't define the sound() behaviour and made it abstract, that's absolutely ok.
Thus, he made this class abstract and made this rule that all Animals should breathe oxygen but the sound they makes will be determined by the gods who creates actual animals (i.e Cat, Dog etc).
Now, the Cat creator God, Dog creator God e.t.c came into picture.
Cat Class
public class Cat extends Animal{
public void sound(){
System.out.println("Cats Meao");
}
public void catRelated(){
System.out.println("It loves sleeping.");
}
}
Dog Class
public class Dog extends Animal{
public void sound(){
System.out.println("Dog Barks");
}
public void dogRelated(){
System.out.println("Very obidient.");
}
}
Thus, we have the below hierarchy :
So we have seen how Animal exists in various forms. Since Animal is abstract, we cannot create any object out of it. Also if you think in reality 'Animal' does not exist. But Cat, Dog etc exists and thus we can create Cat or Dog objects.
Now, comes the most vital part. Creating Cat and Dog objects using the Animal reference. Also known as Dynamic Binding. Little tricky but used everywhere.
Class Test{
public static void main(String[] arg){
Animal animalCat = new Cat();
Animal animalDog = new Dog();
animalCat.sound(); // Calls the sound() behaviour of Cat.
animalDog.sound(); // Calls the sound() behaviour of Dog.
animalCat.breathe(); // Calls the breathe() behaviour of Animal.
animalDog.breathe(); // Calls the breathe() behaviour of Animal.
}
}
Above we have seen something new. The Animal reference variable 'animalCat' is holding a Cat object.
Story :
Although it looks strange for a while, but think logically, the Animal creator God has created the 'Animal' class. And did set the rules which Cat/Dog creator God has to obey. Being a master of Cat/Dog creator he should have the access to their objects as well. Sounds ok?
Now, lets dig the below line:
Animal animalCat = new Cat();
Here Animal is the Refrence Type, 'animal1' is the refrence variable and 'new Cat()' is the Instance/object.
Story :
Ok think again, Animal creator God knows about the sound() and breathe() behaviour which he had declared for the Cat & Dog creator God.
But what about the behavious/methods declared by Cat/Dog creator(i.e dogRelated() and catRelated())? That is completely specific to Cat/Dog class.
Then how will Animal creator know about dogRelated() and catRelated().
And here comes the concept of casting.
Class Test{
public static void main(String[] arg){
Animal animalCat = (Cat)new Cat();
Animal animalDog = (Dog)new Dog();
animalCat.sound(); // Calls the sound() behaviour of Cat.
animalDog.sound(); // Calls the sound() behaviour of Dog.
animalCat.breathe(); // Calls the breathe() behaviour of Animal.
animalDog.breathe(); // Calls the breathe() behaviour of Animal.
animalCat.catRelated();
animalDog.dogRelated();
}
}
Animal animalCat = (Cat)new Cat();
We are specifying '(Cat)' in brackets. That is called as casting. The Animal creator doesn't know about the catRelated() behaviour as it's defined by the Cat creator. The Animal creator only knows about the sound() and breathe() behaviour. So, if he wants to access the catRelated behaviour of Cat, casting should be used.