Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows objects to be treated as instances of their parent class rather than their actual derived class. This makes your code more flexible and extensible, enabling you to write reusable and maintainable code.
In this blog post, we’ll explore polymorphism in C# through a classic example: drawing shapes. We’ll demonstrate how to use a common interface or base class to work with different shapes polymorphically.
What is Polymorphism?
Polymorphism allows a method to behave differently based on the object that invokes it. In C#, this can be achieved through:
- Method Overriding: Achieved using virtual methods and the
override
keyword. - Interface Implementation: Implementing methods from a shared interface.
Using polymorphism, you can invoke a method on an object without knowing its exact type at compile time.
Example: Drawing Shapes
Let’s create a program where different shapes (e.g., Circle, Rectangle, Triangle) are drawn using polymorphism.
Step 1: Define a Base Class
The base class will declare a Draw
method that can be overridden by derived classes.
public abstract class Shape
{
public abstract void Draw();
}
Step 2: Create Derived Classes
Each shape will inherit from the Shape
class and implement the Draw
method.
Circle:
public class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing a Circle.");
}
}
Rectangle:
public class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing a Rectangle.");
}
}
Triangle:
public class Triangle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing a Triangle.");
}
}
Step 3: Use Polymorphism with a List
Now, let’s create a list of shapes and use polymorphism to invoke the Draw
method on each shape.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Create a list of shapes
List<Shape> shapes = new List<Shape>
{
new Circle(),
new Rectangle(),
new Triangle()
};
// Iterate through the list and draw each shape
foreach (var shape in shapes)
{
shape.Draw();
}
}
}
Output:
Drawing a Circle.
Drawing a Rectangle.
Drawing a Triangle.
Benefits of Polymorphism in This Example
- Extensibility:
- Adding a new shape (e.g.,
Pentagon
) requires only creating a new class that overrides theDraw
method. No changes are needed in the existing code.
- Adding a new shape (e.g.,
- Code Reusability:
- The
shapes
list and theforeach
loop do not need to know the specific types of shapes. They rely on the base class/interface.
- The
- Reduced Complexity:
- The code adheres to the Open/Closed Principle (OCP) from SOLID principles, meaning it is open for extension but closed for modification.
Key Points to Remember
- Base Class vs. Interface: While this example uses an abstract base class, you could achieve similar results with an interface.
public interface IShape { void Draw(); }
This approach is useful if you want to avoid inheritance or support multiple base types. - Virtual vs. Abstract Methods: Use
virtual
for methods that provide a default implementation, andabstract
for methods that must be overridden. - Type Safety: Using a common base class or interface ensures type safety while allowing flexibility.
Conclusion
Polymorphism is a powerful feature in C# that simplifies working with different types of objects in a consistent way. By designing with polymorphism in mind, you can create extensible and maintainable systems that handle diverse behaviors seamlessly.
This example demonstrates how polymorphism enables you to build flexible code that works uniformly across different object types. Try expanding the example by adding new shapes or implementing additional behaviors to see polymorphism in action!