Advertisement
Intermediate C# Lesson 6 of 10

Lesson 6: Polymorphism & Overriding in C#

Polymorphism (literally "many forms") is the third pillar of OOP. It allows one method call to execute different behaviors depending on the object's actual type. This lesson shows how to leverage polymorphism to write flexible, extensible code.

Advertisement

What Is Polymorphism?

Polymorphism lets you treat objects of different types through a common interface. A single method call can trigger different behaviors:

public class Shape
{
    public virtual void Draw()
    {
        Console.WriteLine("Drawing a shape");
    }
}

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

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

// Polymorphism in action
List<Shape> shapes = new List<Shape>
{
    new Circle(),
    new Square(),
    new Shape()
};

foreach (var shape in shapes)
{
    shape.Draw();  // Calls the correct method for each type
}

Compile-Time vs Runtime Polymorphism

Compile-time polymorphism (method overloading) is resolved at compile time. Runtime polymorphism (virtual/override) is resolved at runtime based on the actual object type:

// Compile-time: Overloading
public class Calculator
{
    public int Add(int a, int b) => a + b;
    public double Add(double a, double b) => a + b;
    public string Add(string a, string b) => a + b;
}

// Runtime: Virtual/Override
public class Animal
{
    public virtual void Speak() => Console.WriteLine("Generic sound");
}

public class Dog : Animal
{
    public override void Speak() => Console.WriteLine("Woof!");
}

// Compile-time decision
var calc = new Calculator();
calc.Add(5, 10);      // Calls int version
calc.Add(5.5, 10.5);  // Calls double version

// Runtime decision
Animal animal = new Dog();
animal.Speak();       // Calls Dog.Speak() at runtime

Override vs New

Use override to provide a new implementation of a virtual method. Use new to hide the parent method entirely (not recommended):

public class Animal
{
    public virtual void Speak() => Console.WriteLine("Generic sound");
}

public class Dog : Animal
{
    public override void Speak() => Console.WriteLine("Woof!");  // ✓ Correct
}

public class Cat : Animal
{
    public new void Speak() => Console.WriteLine("Meow!");  // ✗ Avoid — hides parent
}
Advertisement

🧠 Quick Check — Lesson 6

Polymorphism allows the same method call to execute different behavior based on what?

Lesson Summary

Polymorphism means "many forms" — the same method call can execute different behavior.

Compile-time polymorphism (overloading) is resolved at compile time based on parameter types.

Runtime polymorphism (virtual/override) is resolved at runtime based on the actual object type.

Use override to customize a virtual method in child classes.

Polymorphism makes code flexible and extensible — add new types without changing existing code.

Up Next

Lesson 7: Abstract Classes & Methods

Next Lesson →