Polymorphism
Polymorphism is one of the four fundamental principles of object-oriented programming (OOP) in C#. It allows objects of different types to be treated as instances of a common base type. This enables a single interface to be utilized with various underlying data types. In C#, there are two types of polymorphism:
- Compile-time polymorphism (also known as static polymorphism)
- Run-time polymorphism (also known as dynamic polymorphism)
Compile-Time Polymorphism
Compile-time polymorphism is achieved through method overloading and operator overloading. This form of polymorphism is resolved during the compilation of the code.
Example of Compile-Time Polymorphism
using System;
class Calculator
{
// Method to add two integers
public int Add(int a, int b)
{
return a + b;
}
// Overloaded method to add three integers
public int Add(int a, int b, int c)
{
return a + b + c;
}
// Overloaded method to add two doubles
public double Add(double a, double b)
{
return a + b;
}
}
class Program
{
static void Main()
{
Calculator calc = new Calculator();
Console.WriteLine(calc.Add(2, 3)); // Calls Add(int, int)
Console.WriteLine(calc.Add(1, 2, 3)); // Calls Add(int, int, int)
Console.WriteLine(calc.Add(2.5, 3.5)); // Calls Add(double, double)
}
}
Run-Time Polymorphism
Run-time polymorphism is achieved through method overriding. This type of polymorphism is resolved at run time. Method overriding allows a derived class to provide a specific implementation for a method that is already defined in its base class
Example of Run-Time Polymorphism
using System;
// Base class
class Animal
{
// Virtual method to be overridden in derived classes
public virtual void Speak()
{
Console.WriteLine("The animal makes a sound.");
}
// Method to display the animal's type
public void DisplayType()
{
Console.WriteLine("This is an animal.");
}
}
// Derived class
class Dog : Animal
{
// Overriding the Speak method
public override void Speak()
{
Console.WriteLine("The dog barks.");
}
// Method specific to Dog
public void Fetch()
{
Console.WriteLine("The dog fetches the ball.");
}
}
// Derived class
class Cat : Animal
{
// Overriding the Speak method
public override void Speak()
{
Console.WriteLine("The cat meows.");
}
// Method specific to Cat
public void Scratch()
{
Console.WriteLine("The cat scratches the furniture.");
}
}
class Program
{
static void Main()
{
// Create instances of Dog and Cat
Animal myDog = new Dog();
Animal myCat = new Cat();
// Demonstrate run-time polymorphism
myDog.Speak(); // Outputs: The dog barks.
myCat.Speak(); // Outputs: The cat meows.
// Demonstrate base class method
myDog.DisplayType(); // Outputs: This is an animal.
myCat.DisplayType(); // Outputs: This is an animal.
// Directly accessing methods specific to Dog and Cat
Dog specificDog = new Dog();
Cat specificCat = new Cat();
specificDog.Fetch(); // Outputs: The dog fetches the ball.
specificCat.Scratch(); // Outputs: The cat scratches the furniture.
}
}
Benefits of Polymorphism
- Code Reusability: Polymorphism enables code reuse by allowing a base class to manage common functionality while derived classes provide specific implementations.
- Maintainability: Code becomes easier to maintain and extend because changes in the base class automatically affect derived classes.
- Flexibility: Polymorphism enhances flexibility by permitting objects to be treated as instances of their base type, which facilitates easier integration and interaction among different objects.
- Dynamic Behavior: Polymorphism supports dynamic method binding at runtime, ensuring that the appropriate method implementation is called based on the actual object type.
