Polymorphism is one of the four fundamental concept for learning object oriented programming.
The word polymorphism has been derived from 2 greek words “poly” and “morph” where poly means many and morph means form.
Polymorphism means an object have different forms and each different form performs same action/task in multiple/different ways.
Polymorphism is generally used to achieve the inheritance mechanism.
Let’s see polymorphism with real word example,
Tony can speak three languages i.e., Gujarati, Hindi and English.
Now Tony will speak Gujarati language with the person who knows Gujarati. Similarly, tony will speak English with the person who knows English and speaks Hindi with the person who knows Hindi.
Here Tony perform one single task that is Speaking. But, the implementation of speaking is different based on language tony speaks. Here, speaking can be in three forms.
So here Tony is the object of the class and speaking is the polymorphism.
Polymorphism in dart is supported only in form of runtime polymorphism (For ex : method overriding etc).
Here we need to understand some concepts before learning polymorphism which are
- Up-Casting
- Down-Casting
Up-Casting
Up-Casting is the process of converting a reference of the subclass type to the super class type.
However converting the reference of subclass to superclass will not convert the object to its super type.
It just converts the child object to a more general form(base form) or say it treats the child object as super object.
For ex :
class Shape
{
}
class Triangle extends Shape
{
}
void main()
{
// Up-casting
Shape s=(Shape) new Triangle();
// It is same as Shape s=(Shape) new Triangle();
Shape s=new Triangle();
// Up-casting is done automatically via system.
}
Down-Casting
Down-casting is the process of converting a reference of the superclass type to the sub class type.
Down-casting needs to be done manually by programmer.
For ex :
void main()
{
// here runtime type of a is Triangle()
Animal anim=new Triangle();
Triangle tri=a;
}
Down-casting is casting the superclass object reference to subclass reference.
Down-casting can be done only if the runtime type of the superclass (i.e., anim’s runtime type is Triangle) must be to the specific subclass reference(i.e., tri’s runtime type is Triangle) in which we are Down-casting.
For ex :
void main()
{
// here runtime type of a is Animal()
Animal anim=new Animal();
Triangle tri=a;
}
Here runtime type of superclass reference doesn’t match with the subclass reference in which we are Down-casting. Which will generate ClassCastException.
That’s why Up-casting is safer than Down-casting as it is done automatically.
Up-casting and Down-casting both are done at runtime.
Unlike other object oriented programming languages, Dart only supports runtime polymorphism(for ex : function overriding)
Runtime Polymorphism
Runtime polymorphism is the process of calling the overridden function at runtime(at the time of program execution) instead of compile time.
Let’s take an example to understand the polymorphism in better way.
Suppose, we want to draw shapes for different classes. So, we’ll create a class Shape with method drawShape() which draws a Circle Shape.
Let’s create a Shape class which has a method drawShape().
class Shape
{
drawShape()
{
print(” Circle Shape”);
}
}
Now there are 3 more sub-classes Triangle, Square and Hexagon of Shape class. All these subclasses will call drawMethod() to draw circle shape.
Now, you will be thinking why we’re creating a Parent class shape and creating a method drawShape() in it.
Because it’s a better way to create a one single method drawShape() and access that method from each classes who wants to draw shape instead of writing that method in each class(writing the same method will consume your memory as well as time).
That’s why we will use the reusability concept of inheritance.
For ex :
class Shape
{
drawShape()
{
print(" Circle Shape");
}
}
class Triangle extends Shape
{
}
class Square extends Shape
{
}
class Hexagon extends Shape
{
}
void main(){
// Upcasting
Shape T=new Triangle();
Shape S=new Square();
Shape H=new Hexagon();
T.drawShape();
S.drawShape();
H.drawShape();
}
Output :
Circle Shape
Circle Shape
Circle Shape
Now, if triangle class don’t want to draw circle shape from its super class. So, what we can do is that we’ll create a drawShape() method in Triangle class with its own implementation.
For ex :
class Shape
{
drawShape()
{
print(" Circle Shape");
}
}
class Triangle extends Shape
{
drawShape()
{
print("Triangle Shape");
}
}
class Square extends Shape
{
}
class Hexagon extends Shape
{
}
void main()
{
// Upcasting
Shape T=new Triangle();
Shape S=new Square();
Shape H=new Hexagon();
T.drawShape();
S.drawShape();
H.drawShape();
}
Output :
Triangle Shape
Circle Shape
Circle Shape
So in above class when you called the method with the object of class Triangle T, it will first check the method drawShape() in Triangle class. If it’s present then drawShape() method from class Triangle will be implemented else it will check for the accessible drawShape() method in its superclass Shape.
If it’s present in Shape class then drawShape() method of Shape will be executed else it will further check for the accessible drawShape() method in its Super class.
This process will be continued till either the required method drawShape() is found or the highest super class is reached.
This process is known as method overriding.
Polymorphism is the process in which the output of your program depends on the inputs you provide.
For ex :
In above case, the drawShape() method of which class will be depends on the object of particular class accesses it.
So explore more cases of polymorphism by performing some critical programs and practice it to make your development code more convenient to use.
Feel free to ask your questions in the comment section. Keep reading and commenting your suggestions to make toastguyz a better site to learn different programming languages.