Labs ICT
โญ Pro Login

Polymorphism

Polymorphism means "many forms." In programming, it lets different objects respond to the same method call in their own way. You already saw a preview of this with method overriding. Now let us go deeper.

Runtime Polymorphism

This is the most common type. You use a base class reference to point to a derived class object, and C# figures out which method to call at runtime:

class Shape
{
    public string Color { get; set; }

    public virtual double CalculateArea()
    {
        return 0;
    }
}

class Circle : Shape
{
    public double Radius { get; set; }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}

class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public override double CalculateArea()
    {
        return Width * Height;
    }
}

// Polymorphism in action
Shape[] shapes = new Shape[]
{
    new Circle { Radius = 5 },
    new Rectangle { Width = 4, Height = 6 },
    new Circle { Radius = 3 }
};

foreach (Shape shape in shapes)
{
    Console.WriteLine($"Area: {shape.CalculateArea():F2}");
}
// Area: 78.54
// Area: 24.00
// Area: 28.27

Even though the array type is Shape, each object calls its own version of CalculateArea(). C# decides at runtime which method to invoke based on the actual object type.

The abstract Keyword

Sometimes you want to force derived classes to implement a method. You can make the base method abstract:

abstract class Shape
{
    public string Color { get; set; }

    // No implementation โ€” derived classes MUST override this
    public abstract double CalculateArea();
}

class Circle : Shape
{
    public double Radius { get; set; }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}

An abstract class cannot be instantiated directly. You cannot do new Shape(). It exists only to be inherited from. This is useful when you want to define a contract that all derived classes must follow.

The is and as Keywords

When working with polymorphism, you often need to check or convert types:

Shape shape = new Circle { Radius = 5 };

// Check the type
if (shape is Circle)
{
    Console.WriteLine("It is a circle!");
}

// Safe casting with pattern matching
if (shape is Circle c)
{
    Console.WriteLine($"Radius: {c.Radius}");
}

// Using as (returns null if conversion fails)
Circle? maybeCircle = shape as Circle;
if (maybeCircle != null)
{
    Console.WriteLine($"Radius: {maybeCircle.Radius}");
}

๐Ÿงช Quick Quiz

What is polymorphism?