Lesson 8 — Polymorphism in C#

Polymorphism is the fourth and final pillar of Object-Oriented Programming (OOP).
The word polymorphism comes from Greek:

  • Poly → many
  • Morph → forms

Meaning:

Polymorphism = One action, many forms.

In C#, this means a single function can behave differently depending on the context.

This is one of the most powerful concepts in OOP.


🌟 What is Polymorphism?

Polymorphism allows methods or objects to behave in multiple different ways depending on:

  • Number of parameters
  • Type of parameters
  • Which class is calling the method

There are two types of polymorphism in C#:


🧱 Types of Polymorphism in C#

✔ 1. Compile-Time Polymorphism

(Also called Static Polymorphism / Method Overloading)

✔ 2. Run-Time Polymorphism

(Also called Dynamic Polymorphism / Method Overriding)

We will explore both with examples.


🧩 1️⃣ Compile-Time Polymorphism (Method Overloading)

Method overloading happens when you create multiple methods with the same name, but different:

  • Number of parameters
  • Type of parameters
  • Order of parameters

The compiler decides which method to call at compile time.


🧑‍💻 Example — Method Overloading

public class Calculator
{
    // Method 1
    public int Add(int a, int b)
    {
        return a + b;
    }

    // Method 2
    public double Add(double a, double b)
    {
        return a + b;
    }

    // Method 3
    public int Add(int a, int b, int c)
    {
        return a + b + c;
    }
}

Using the class:

Calculator calc = new Calculator();
Console.WriteLine(calc.Add(2, 3));           // 5
Console.WriteLine(calc.Add(2.5, 3.5));       // 6.0
Console.WriteLine(calc.Add(2, 3, 4));        // 9

✔ Same method name → different forms
✔ Output depends on parameters
✔ Decided at compile time


🧩 2️⃣ Run-Time Polymorphism (Method Overriding)

Run-time polymorphism happens when a child class overrides a method of the parent class.

This is achieved using:

  • virtual → in base class
  • override → in derived class

The decision of which method to call happens at runtime.


🧑‍💻 Example — Method Overriding

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Some sound...");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Bark!");
    }
}

public class Cat : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Meow!");
    }
}

Using the class:

Animal a;

a = new Dog();
a.MakeSound();      // Bark!

a = new Cat();
a.MakeSound();      // Meow!

✔ Same method → different behavior
✔ Decided at runtime
✔ This is the best real-world demonstration of polymorphism


🐶 Real-World Analogy of Polymorphism

Imagine the method:

MakeSound()

Different animals produce different sounds for the same action:

AnimalOutput
DogBark
CatMeow
CowMoo
LionRoar

The action is the same → MakeSound()
The result is different → Different implementation

This is polymorphism.


🎨 Another Analogy — Pressing the “Start” Button

In a Car → Starts the engine
In a Laptop → Boots the system
In a Washing Machine → Starts washing

Same action → different results → polymorphism


🔄 Comparison: Overloading vs Overriding

FeatureMethod OverloadingMethod Overriding
TypeCompile-time polymorphismRuntime polymorphism
Used InSame classParent-child classes
Method SignatureMust differMust be same
KeywordsNonevirtual + override
When Used?Same action, different inputsSame action, different implementations

🧠 Why Polymorphism is Important?

✔ Supports flexibility
✔ Enables code to work with parent types
✔ Makes frameworks possible
✔ Allows different implementations with same interface
✔ Required for design patterns and scalable architecture

Example:

public void ProcessPayment(Payment payment)
{
    payment.Pay();
}

Regardless of whether the payment is:

  • UPI
  • CreditCard
  • NetBanking

The same method works → polymorphism


🧱 Mini Project Example — Drawing Shapes

Base Class:

public abstract class Shape
{
    public abstract void Draw();
}

Derived Classes:

public class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing Circle...");
    }
}

public class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing Rectangle...");
    }
}

Using Polymorphism:

Shape s;

s = new Circle();
s.Draw();   // Drawing Circle...

s = new Rectangle();
s.Draw();   // Drawing Rectangle...

✔ Same method Draw()
✔ Different results


📝 Mini Exercise

Create:

  • Base class: Vehicle with method Start()
  • Derived classes: Car, Bike
  • Override the Start() method in both classes

Print:
“Car starting…”
“Bike starting…”


🔍 FAQs

Q1: Is overload also called static polymorphism?

Yes. Overloading is also known as static polymorphism.

Q2: Can constructors be overloaded?

Yes, constructors support overloading.

Q3: Can constructors be overridden?

No. Constructors cannot be overridden.

Q4: Which is faster — overloading or overriding?

Overloading is faster since it is resolved at compile time.


🎉 Conclusion

Polymorphism allows code to behave in multiple ways, improving flexibility and reusability.
You now understand:

✔ Method Overloading
✔ Method Overriding
✔ Compile-time vs Run-time polymorphism
✔ Real-world examples
✔ C# implementation

Polymorphism is essential for:

  • Design patterns
  • Dynamic behavior
  • Framework development
  • Real-world applications