The term polymorphism originates from the fusion of "poly" and "morphism", where "poly" denotes many and "morphism" signifies form. This concept allows a single task to be executed in multiple forms, stemming from Greek origins. The essence of polymorphism lies in enabling the utilization of a singular function name for varied functionalities. Within Object-Oriented Programming (OOP), polymorphism harmonizes with three fundamental principles: inheritance, encapsulation, and polymorphism itself. By embracing polymorphism, software development gains enhanced adaptability, code reusability, and ease of maintenance.
Simple Example of Polymorphism
Let's consider an example to explain polymorphism in C#.
Example
using System;
class Example
{
static void Main()
{
int num1 = 50; // integer variable
int num2 = 25; // integer variable
string firstWord = "over"; // string variable
string secondWord = "loading";
Console.WriteLine("Sum of num1 and num2 = " + (num1 + num2));
Console.WriteLine("Concatenated string = " + (firstWord + secondWord));
}
}
Output:
Sum of num1 and num2 = 75
Concatenated string = overloading
Explanation:
In this instance, we are working with two different data types: integers and strings. Following this, we are utilizing the addition (+) operator. The initial (+) operator performs addition on numerical values, while the subsequent one concatenates two string inputs. To display the result, we employ the Console.WriteLine method.
Types of Polymorphism
There are mainly two types of polymorphism in C#.
The <style> CSS class defines the styling for a placeholder diagram. This includes a background with a linear gradient, border radius, padding, margin, and text alignment. Within the placeholder diagram, there are specific styles for the placeholder icon and text. The icon has a font size of 3rem and a margin at the bottom, while the text is styled with a color of #9ca3af and a font size of 1rem. </style>
Here, we will examine these genetic variations individually.
Compile-time Polymorphism
In C# programming language, compile-time polymorphism is referred to as early binding and static polymorphism. This feature allows developers to create several methods with identical names but varying parameters.
The <style> element is styled with a linear gradient background, rounded corners, padding, and centered text. Inside, there is an icon with a size of 3 rem and text with a color of #9ca3af and a font size of 1 rem.
It is accomplished through the utilization of method overloading and operator overloading in C#.
Note: When a method call decides the actual function during the compilation process of a program, it is known as compile-time polymorphism.
a) Function Overloading
In C#, function overloading stands as a crucial concept within the realm of object-oriented programming. It offers a mechanism for a class to possess identical names while differing in their parameters. This feature can be executed by adjusting either the quantity of arguments or by modifying the arguments themselves.
C# Compile-Time Polymorphism Example using Function Overloading
Let's consider a basic example to demonstrate compile-time polymorphism through function overloading in C#.
Example
using System;
class Number
{
// declaration of method with two int parameters
public int Add(int a, int b)
{
return a + b;
}
// method with three int parameters
public int Add(int a, int b, int c)
{
return a + b + c;
}
// method with parameters type double
public double Add(double a, double b)
{
return a + b;
}
}
class Program
{
static void Main()
{
Number num = new Number();
Console.WriteLine("The Sum of the two numbers is " + num.Add(100, 200));
Console.WriteLine("The Sum of the three numbers is " + num.Add(100, 200, 300));
Console.WriteLine("The Sum of two floating numbers is " + num.Add(20.5, 30.7));
}
}
Output:
The Sum of the two numbers is 300
The Sum of the three numbers is 600
The Sum of two floating numbers is 51.2
Explanation:
In this instance, we've defined a class called Number, housing three methods sharing a common name but accepting varying parameters. Subsequently, an object of the class (Number) is instantiated within the primary function, invoking the method (Addition) thrice. Ultimately, the Console.WriteLine method is employed to display the result.
b) Operator Overloading
In C#, operator overloading enables a single operator to carry out various operations. This feature pertains to user-defined data types. It can be implemented by utilizing a range of operators like +, -, *, = =, <<, >, and more. In C#, when employing operator overloading, it is necessary for at least one operand to be a user-defined data type.
In this C# tutorial, we will explore an instance of compile-time polymorphism through the concept of operator overloading.
Let's consider a scenario to demonstrate compile-time polymorphism through the utilization of operator overloading in C#.
Example
using System;
class Comp
{
public int real, imag;
public Comp(int r, int i)
{
real = r;
imag = i;
}
// Applying the + operator
public static Comp operator + (Comp a1, Comp a2)
{
return new Comp(a1.real + a2.real, a1.imag + a2.imag);
}
public void Show()
{
Console.WriteLine($"{real} + {imag}i");
}
}
class C# Tutorial
{
static void Main()
{
Comp a1 = new Comp(2, 3);
Comp a2 = new Comp(4, 5);
Comp sum = a1 + a2;
sum.Show();
}
}
Output:
6 + 8i
Explanation:
In this instance, we are examining a class called Comp, which comprises of a pair of public integer variables (real and imag) and three functions. An initial function is employed to assign values to either real or imag, followed by the utilization of the overloaded + operator function to sum two Comp instances. Subsequently, a Show function is employed to exhibit the complex number. Within the primary function, we instantiate two complex numbers, perform addition using the overloaded + operator, and exhibit the outcome.
Runtime Polymorphism
In C#, the concept of runtime polymorphism is alternatively referred to as dynamic polymorphism or late binding. This phenomenon occurs when the specific method to be executed is decided during the program's execution rather than at compile time. Runtime polymorphism is achieved through method overriding, wherein a subclass offers its own version of a virtual method declared in the superclass.
a) Function Overriding
In C#, function overriding is a key feature of object-oriented programming that enables a derived class to redefine a method that is already defined in its base class. The base method should use the virtual keyword, and the derived classes should use the override keyword to provide their implementation. It enables a child class to give a specific behaviour for a method, which is already defined in the parent class.
In this example, we will demonstrate C# runtime polymorphism through function overriding. By redefining a method in a derived class that is already present in the base class, we can showcase how the method called at runtime depends on the object type.
Let's consider a scenario to demonstrate run-time polymorphism by employing function overriding in C#.
Example
using System;
class Animal
{
public virtual void Speak()
{
Console.WriteLine("The Animal speaks");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("The dog barks");
}
}
class C# Tutorial
{
static void Main()
{
Animal animal = new Dog(); // Base class reference, derived class object
animal.Speak(); // Calls Dog's Speak() at runtime
}
}
Output:
The dog barks
Explanation:
In this illustration, a fundamental class Animal is defined with the virtual method Speak. Subsequently, a subclass Dog is established inheriting characteristics from the base class and utilizing its functionalities. Within the primary function, an object of the subclass (Dog) is instantiated, invoking the Speak function to display the desired result.
b) Virtual Method
In C#, a virtual method is implemented within the parent class. The virtual keyword is employed to establish a method as virtual. It is utilized in a parent class member to indicate that the parent class can be redefined in a child class. In the child class, the override keyword is utilized to provide a fresh implementation of a parent class member that was previously marked as virtual.
Virtual Method Example in C#
Let's consider a basic example to explain method overriding by using the virtual method in C#.
Example
using System;
class Shape
{
public virtual void Draw()
{
Console.WriteLine("This is the shape Drawing");
}
}
class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("The is the shape Circle");
}
}
class Square : Shape
{
public override void Draw()
{
Console.WriteLine("This is the shape square");
}
}
class Program
{
static void Main()
{
Shape s;
s = new Circle();
s.Draw();
s = new Square();
s.Draw();
}
}
Output:
This is the shape Circle
This is the shape square
Explanation:
In this instance, a class named Shape is utilized, featuring the virtual function Draw. Following this, a subclass named Square is established, inheriting from the parent class to leverage the functionalities of the base class. Within the primary function, an object of the Shape class is instantiated, and the Draw function is invoked to display the result.
Use Cases of Polymorphism in C#
There are several use cases of polymorphism in C#. Some of them are as follows:
- It allows us to write generic code in the base class and modify it in the derived classes.
- It is based on the object type that helps us to choose at runtime which method to execute.
- It helps to reduce code duplicity by defining common behavior in a base class and modifying it.
- It allows us to implement multiple classes in the same interface and provide their own functionality.
Difference between Compile Time and Run-time Polymorphism
There exist various distinctions between compile-time and run-time polymorphism in C#. Here are a few key variances:
| Compile Time Polymorphism | Run Time Polymorphism |
|---|---|
| It is also known as Early binding. | It is also known as Late binding. |
| The method call is decided during the compilation of the code. | The method call is decided during program execution. |
| It is achieved via method overloading or operator overloading. | It is implemented through method overriding. |
| In Compile-time polymorphism, inheritance is not involved. | Inheritance is involved in run-time polymorphism. |
| It is less flexible. | It is more flexible. |
Conclusion
In summary, the utilization of polymorphism in C# plays a pivotal role in the development of software applications. This concept stands as a fundamental element of C# object-oriented programming. Polymorphism enables developers to employ the same function name for various functionalities, thereby enhancing code reusability, adaptability, and manageability.
C# Polymorphism FAQs
1) What is Polymorphism in C#?
In C#, polymorphism is derived from the fusion of "poly" and "morphism". "Poly" signifies many, while "morphism" refers to form. Essentially, it denotes a single entity existing in multiple forms. This feature enables the utilization of a shared function name for distinct functionalities.
There are two main types of polymorphism in C#:
- Compile-time Polymorphism:
- This type of polymorphism is achieved through method overloading and operator overloading.
- Method overloading allows a class to have multiple methods with the same name but different parameters.
- Operator overloading enables operators to have different implementations based on the types of operands.
- Runtime Polymorphism:
- Runtime polymorphism is achieved through method overriding.
- Method overriding allows a subclass to provide a specific implementation of a method that is already provided by its superclass.
- It is also known as dynamic polymorphism as the method that will be called is decided at runtime based on the type of object.
There are two forms of polymorphism in C#.
- Static Polymorphism
- Dynamic Polymorphism
3) What are the keywords employed for implementing run-time polymorphism in C#?
The virtual, override, and abstract keywords are essential for implementing runtime polymorphism in programming.
4) Why is polymorphism important in C#?
Polymorphism plays a crucial role for software developers when crafting an application. It enables the utilization of a single function name for various functionalities, thereby enhancing code adaptability, sustainability, and recyclability.
5) How do overloading and overriding methods differ in C#?
The variance between method overloading and method overriding is outlined below.
Method Overloading:
Method Overloading is a type of Compile-time Polymorphism which enables the creation of multiple methods with identical names but varying signatures.
Method Overriding:
Method Overriding is a type of run-time polymorphism that enables the definition of multiple functions with identical signatures. This feature permits a subclass to replace a method inherited from its superclass.