C# Polymorphism - Complete Guide
Introduction to Polymorphism
Polymorphism in C# is an important concept in object-oriented programming that allows objects of different classes to be accessed through a common base class reference.
The word 'polymorphism' means 'many forms'. In practice, it lets the same method call produce different behavior depending on the actual object type.
C# supports compile-time polymorphism (method overloading) and runtime polymorphism (method overriding). These features make code more flexible and easier to extend.
Types of Polymorphism
C# demonstrates polymorphism through overloading, overriding, and method hiding:
Example
using System;
namespace PolymorphismExample
{
public class Shape
{
public virtual void Draw()
{
Console.WriteLine("Drawing a generic shape");
}
public void Draw(string color)
{
Console.WriteLine($"Drawing a generic shape with {color} color");
}
public void Draw(string color, int thickness)
{
Console.WriteLine($"Drawing a generic shape with {color} color and {thickness}px thickness");
}
public virtual double CalculateArea() => 0;
}
public class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius) => Radius = radius;
public override void Draw()
{
Console.WriteLine($"Drawing a circle with radius {Radius}");
}
public override double CalculateArea() => Math.PI * Radius * Radius;
public new void Draw(string color)
{
Console.WriteLine($"Drawing a circle with {color} color");
}
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
public override void Draw()
{
Console.WriteLine($"Drawing a rectangle {Width}x{Height}");
}
public override double CalculateArea() => Width * Height;
}
public class Triangle : Shape
{
public double Base { get; set; }
public double Height { get; set; }
public Triangle(double @base, double height)
{
Base = @base;
Height = height;
}
public override void Draw()
{
Console.WriteLine($"Drawing a triangle with base {Base} and height {Height}");
}
public override double CalculateArea() => 0.5 * Base * Height;
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("=== Compile-time Polymorphism (Overloading) ===");
Shape shape = new Shape();
shape.Draw();
shape.Draw("red");
shape.Draw("blue", 2);
Console.WriteLine("\n=== Runtime Polymorphism (Overriding) ===");
Shape[] shapes = {
new Circle(5),
new Rectangle(4, 6),
new Triangle(3, 4),
new Shape()
};
foreach (var s in shapes)
{
s.Draw();
Console.WriteLine($"Area: {s.CalculateArea():F2}\n");
}
Console.WriteLine("=== Method Hiding vs Overriding ===");
Circle circle = new Circle(3);
Shape shapeCircle = new Circle(3);
circle.Draw("green"); // Circle version
shapeCircle.Draw("green"); // Shape version
Console.WriteLine("\n=== Type Casting and Polymorphism ===");
foreach (var s in shapes)
{
if (s is Circle c)
Console.WriteLine($"This is a circle with radius {c.Radius}");
else if (s is Rectangle r)
Console.WriteLine($"This is a rectangle {r.Width}x{r.Height}");
else if (s is Triangle t)
Console.WriteLine($"This is a triangle with base {t.Base} and height {t.Height}");
else
Console.WriteLine("This is a generic shape");
}
}
}
}
Output
=== Compile-time Polymorphism (Overloading) === Drawing a generic shape Drawing a generic shape with red color Drawing a generic shape with blue color and 2px thickness === Runtime Polymorphism (Overriding) === Drawing a circle with radius 5 Area: 78.54 Drawing a rectangle 4x6 Area: 24.00 Drawing a triangle with base 3 and height 4 Area: 6.00 Drawing a generic shape Area: 0.00 === Method Hiding vs Overriding === Drawing a circle with green color Drawing a generic shape with green color === Type Casting and Polymorphism === This is a circle with radius 5 This is a rectangle 4x6 This is a triangle with base 3 and height 4 This is a generic shape