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.
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
}
🧠 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.