Polymorphism is the next fundamental principle of Object-Oriented Programming (OOP). Polymorphism is a Greek word that means many-shaped i.e. one object has many forms or has one name with multiple functionalities.
In C#, there are two types of polymorphism.
Compile-time polymorphism is achieved using method overloading and operator overloading. The method overloading means defining multiple methods with the same name but with different parameters.
Compile-time polymorphism is also known as static binding or early binding. The following code shows the method overloading of Add()
methods, where both methods have the same name and different parameters.
public class MathUtility
{
public int Add(int number1, int number2)
{
return (number1 + number2);
}
public int Add(int number1, int number2, int number3)
{
return (number1 + number2 + number3);
}
}
In the above class, we defined two methods with the same name Add
but with different parameters to achieve method overloading and it is called a compile-time polymorphism in c#.
You can call these methods to achieve a different result.
MathUtility utility = new MathUtility();
utility.Add(2, 3); // 5
utility.Add(2, 3, 4); // 9
Runtime polymorphism is achieved by method overriding which is also known as dynamic binding or late binding. The method overriding means defining methods in parent and child class with the same name and signature but different implementation.
override
& virtual
keywords along with the inheritance principle.Here is the simple example of method overriding, where the Shape
class contains a virtual method CalculateArea()
which we will override in child classes.
public class Shape
{
public virtual double CalculateArea()
{
return 0;
}
}
public class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public override double CalculateArea()
{
return (3.14) * Math.Pow(Radius, 2);
}
}
public class Rectangle : Shape
{
public double Height { get; set; }
public double Width { get; set; }
public Rectangle(double height, double width)
{
Height = height;
Width = width;
}
public override double CalculateArea()
{
return Height * Width;
}
}
As you can see, we have two child classes Circle
and Rectangle
; both classes override the CalculateArea()
method with their own implementation by calculating the area of circle and rectangle respectively.
Now we can create Shape
, Circle
and Rectangle
objects and assign them to Shape
instances.
Shape shape = new Shape();
Shape circle = new Circle(3.0);
Shape rectangle = new Rectangle(3.0, 4.0);
Console.WriteLine("The area of the shape is " + shape.CalculateArea());
Console.WriteLine("The area of the circle is " + circle.CalculateArea());
Console.WriteLine("The area of the rectangle is " + rectangle.CalculateArea());
You can see that both objects can call the CalculateArea()
but the right version of the CalculateArea()
method is not being determined at compile time but determined at runtime.
Let's run the above code and you will see the following output.
The area of the shape is 0
The area of the circle is 28.26
The area of the rectangle is 12
All the examples related to the polymorphism are available in the Polymorphism.cs
file of the source code. Download the source code and try out all the examples for better understandings.