Polymorphism in C#
Learn how one method, object, or interface can behave in different ways in C#.
What is Polymorphism?
Polymorphism is one of the four important pillars of Object-Oriented Programming (OOP).
The word polymorphism comes from two words: Poly means "many" and Morph means "forms".
Therefore, polymorphism means "one thing having many forms."
In C#, polymorphism allows the same method name or reference to perform different operations depending on the situation.
Types of Polymorphism in C#
C# mainly supports two types of polymorphism:
| Type | Also Called | Achieved Using |
|---|---|---|
| Compile-Time Polymorphism | Static / Early Binding | Method Overloading |
| Run-Time Polymorphism | Dynamic / Late Binding | Method Overriding |
1. Compile-Time Polymorphism
Compile-time polymorphism is achieved using method overloading.
In method overloading, multiple methods have the same name but different parameters.
The compiler decides which method should be called during compilation.
Example: Method Overloading
using System;
class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public int Add(int a, int b, int c)
{
return a + b + c;
}
public double Add(double a, double b)
{
return a + b;
}
}
class Program
{
static void Main()
{
Calculator calculator = new Calculator();
Console.WriteLine(calculator.Add(10, 20));
Console.WriteLine(calculator.Add(10, 20, 30));
Console.WriteLine(calculator.Add(10.5, 20.5));
}
}
Output
30 60 31
Program Explanation
| Code | Explanation |
|---|---|
| Calculator | Class containing overloaded Add methods. |
| Add(int, int) | Adds two integer values. |
| Add(int, int, int) | Adds three integer values. |
| Add(double, double) | Adds two decimal values. |
| calculator.Add() | The compiler selects the correct method based on the arguments. |
2. Run-Time Polymorphism
Run-time polymorphism is achieved using method overriding.
In method overriding, a child class provides its own implementation of a method that is already defined in the parent class.
The method that will execute is decided at runtime.
Example: Method Overriding
using System;
class Animal
{
public virtual void Sound()
{
Console.WriteLine("Animal makes a sound");
}
}
class Dog : Animal
{
public override void Sound()
{
Console.WriteLine("Dog barks");
}
}
class Cat : Animal
{
public override void Sound()
{
Console.WriteLine("Cat meows");
}
}
class Program
{
static void Main()
{
Animal animal;
animal = new Dog();
animal.Sound();
animal = new Cat();
animal.Sound();
}
}
Output
Dog barks Cat meows
How This Program Works
-
Animal contains the virtual
Sound()method. -
Dog overrides the
Sound()method. -
Cat also overrides the
Sound()method. -
The variable
animalis of typeAnimal. - At runtime, it can refer to a Dog or Cat object.
- The appropriate overridden method is executed.
virtual and override Keywords
virtual Keyword
The virtual keyword allows a method in
the parent class to be overridden by a child class.
override Keyword
The override keyword is used in the child
class to provide a new implementation of the parent
class method.
class Parent { public virtual void Show() { Console.WriteLine("Parent Show"); } } class Child : Parent { public override void Show() { Console.WriteLine("Child Show"); } }
Parent Reference and Child Object
One of the most important concepts in runtime polymorphism is that a parent class reference can hold a child class object.
Animal animal = new Dog();
Here:
-
Animalis the reference type. -
Dogis the actual object type. - The object is created at runtime.
- The overridden method of Dog is executed.
Example: Payment System 🤓🌍
Polymorphism is commonly used in real-world applications. For example, an application may support different payment methods.
Every payment method can have a common
Pay() method, but each payment type can
implement the method differently.
using System;
class Payment
{
public virtual void Pay()
{
Console.WriteLine("Processing payment");
}
}
class CreditCardPayment : Payment
{
public override void Pay()
{
Console.WriteLine("Payment through Credit Card");
}
}
class UPIPayment : Payment
{
public override void Pay()
{
Console.WriteLine("Payment through UPI");
}
}
class Program
{
static void Main()
{
Payment payment;
payment = new CreditCardPayment();
payment.Pay();
payment = new UPIPayment();
payment.Pay();
}
}
Output
Payment through Credit Card Payment through UPI
Why Polymorphism is Useful Here?
The application can work with the common
Payment type instead of writing separate
logic for every payment method.
Later, we can add another payment type such as
CashPayment without changing the common
payment structure.
Polymorphism with Multiple Objects
A parent class reference can be used to store multiple child objects. This becomes very useful when working with collections and arrays.
using System;
class Animal
{
public virtual void Sound()
{
Console.WriteLine("Animal sound");
}
}
class Dog : Animal
{
public override void Sound()
{
Console.WriteLine("Dog barks");
}
}
class Cat : Animal
{
public override void Sound()
{
Console.WriteLine("Cat meows");
}
}
class Program
{
static void Main()
{
Animal[] animals =
{
new Dog(),
new Cat(),
new Dog()
};
foreach (Animal animal in animals)
{
animal.Sound();
}
}
}
Output
Dog barks Cat meows Dog barks
This is a very important practical use of runtime polymorphism. A single collection can contain different child objects.
Method Overloading vs Method Overriding
| Feature | Overloading | Overriding |
|---|---|---|
| Polymorphism | Compile-Time | Run-Time |
| Classes | Usually same class | Parent and child classes |
| Method Name | Same | Same |
| Parameters | Must be different | Must match overridden method |
| Keywords | No special keyword required | virtual / override commonly used |
| Decision | Compiler | Runtime |
Polymorphism with Abstract Classes
Abstract classes can also be used to achieve runtime polymorphism. An abstract method does not contain an implementation in the parent class.
using System;
abstract class Shape
{
public abstract void Draw();
}
class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing Circle");
}
}
class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing Rectangle");
}
}
class Program
{
static void Main()
{
Shape shape;
shape = new Circle();
shape.Draw();
shape = new Rectangle();
shape.Draw();
}
}
Output
Drawing Circle Drawing Rectangle
Advantages of Polymorphism
- Improves code reusability.
- Reduces duplicate code.
- Makes applications easier to maintain.
- Supports flexible application design.
- Helps implement common behavior with different implementations.
- Makes large applications easier to extend.
- Very useful in enterprise application development.
Common Mistakes
-
Forgetting to use
virtualin the parent method when using the traditional overriding approach. -
Using
newwhen the intention is actually to override a virtual method. - Confusing method overloading with method overriding.
- Trying to override a method that is not virtual, abstract, or already overridable.
- Creating unnecessary inheritance only to use polymorphism.
CIIT Practical Point
In real-world .NET applications, polymorphism is heavily used when designing scalable and maintainable systems.
For example, a project may have a common service or interface and multiple implementations for different business requirements.
This makes the application flexible and easier to extend when new functionality is added.
Important Interview Points
- What is polymorphism?
- What are the types of polymorphism in C#?
- What is compile-time polymorphism?
- What is run-time polymorphism?
- What is method overloading?
- What is method overriding?
- What is the difference between overloading and overriding?
- What is the purpose of virtual?
- What is the purpose of override?
- Can a parent reference hold a child object?
- What is late binding?
- How is polymorphism useful in real-world applications?
Summary
Polymorphism means one thing having many forms. It allows the same method or reference to behave differently depending on the situation.
C# supports compile-time polymorphism through method overloading and run-time polymorphism through method overriding.
Understanding polymorphism is essential for developing flexible, reusable, and maintainable object-oriented applications.
Practice Questions
- Create a Calculator class using method overloading.
- Create a Shape parent class and override Draw() in Circle and Rectangle.
- Create a Vehicle class and override Start() in Car and Bike.
- Create a Payment class and implement different payment types.
- Create an Employee parent class and override CalculateSalary() for different employees.