Polymorphism in C#: Explained with Real-World Examples
Amr Saafan
Founder | CTO | Software Architect & Consultant | Engineering Manager | Project Manager | Product Owner | +27K Followers | Now Hiring!
One fundamental concept within the realm of object-oriented programming (OOP) is polymorphism, a concept that empowers the treatment of objects from different classes as if they were objects of a common base class. This capability fosters the creation of adaptable and reusable code. This blog post is dedicated to exploring the concept of polymorphism in C# and illustrating its functionality through real-world examples.
Understanding Polymorphism
Polymorphism basically translates to “many shapes.” The capacity of objects to assume many forms or kinds is referred to as OOP. With the help of this idea, you may build more general code that can interact with a wide range of objects, resulting in increased adaptability and extensibility for your code.
Method overriding and interfaces are frequently used as two techniques to accomplish polymorphism. Let’s examine both of these techniques in more detail using actual cases.
Method Overriding
A crucial aspect of polymorphism is method overriding. It enables a subclass to offer a particular implementation of a method that has already been specified in its parent class. The parent class method’s name, return type, and parameters should be used for the overridden method in the subclass.
Think of a situation where forms are present, such as circles and rectangles. A Shape base class and the subclasses Circle and Rectangle can be created. Each of these subclasses has the ability to override the CalculateArea method.
class Shape
{
public virtual double CalculateArea()
{
return 0.0;
}
}
class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public override double CalculateArea()
{
return Math.PI * Math.Pow(Radius, 2);
}
}
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 double CalculateArea()
{
return Width * Height;
}
}
In this example, both Circle and Rectangle classes inherit from the Shape class and provide their own implementations of the CalculateArea method. This is an example of method overriding, and it allows us to treat circles and rectangles as shapes while calculating their areas differently.
Now, let’s see polymorphism in action:
Shape circle = new Circle(5.0);
Shape rectangle = new Rectangle(4.0, 6.0);
Console.WriteLine($"Circle Area: {circle.CalculateArea()}"); // Outputs: Circle Area: 78.53981633974483
Console.WriteLine($"Rectangle Area: {rectangle.CalculateArea()}"); // Outputs: Rectangle Area: 24
Here, we create instances of both Circle and Rectangle but store them in variables of type Shape. Despite the variables being of the base type, when we call the CalculateArea method, it invokes the appropriate overridden method based on the actual object type.
This is the essence of polymorphism in C#: code that works with objects of the base class can seamlessly operate on objects of derived classes.
领英推荐
Interfaces and Polymorphism
Interfaces can be used to implement polymorphism in addition to method overriding. Interfaces specify a collection of methods and attributes that a class must implement in order to conform to a contract. An interface instance can be considered to be any class that implements the interface.
Take cellphones and laptops as an example of technological gadgets. To express a device’s ability to be charged, we may create an interface named ICharging.
interface ICharging
{
void Charge();
}
class Smartphone : ICharging
{
public void Charge()
{
Console.WriteLine("Charging the smartphone.");
}
}
class Laptop : ICharging
{
public void Charge()
{
Console.WriteLine("Charging the laptop.");
}
}
In this example, both Smartphone and Laptop classes implement the ICharging interface by providing their own implementations of the Charge method.
Now, we can use polymorphism to charge different devices without worrying about their specific types:
ICharging phone = new Smartphone();
ICharging laptop = new Laptop();
phone.Charge(); // Outputs: Charging the smartphone.
laptop.Charge(); // Outputs: Charging the laptop.
Here, we create instances of Smartphone and Laptop but store them in variables of type ICharging. This allows us to call the Charge method on both objects, demonstrating polymorphism through interfaces.
Conclusion
Polymorphism is a powerful concept in C# that allows you to write flexible, generic, and maintainable code. Whether achieved through method overriding or interfaces, polymorphism enables you to treat objects of different classes as instances of a common base class or interface, promoting code reusability and flexibility.
By understanding and applying polymorphism in your C# projects, you can create code that is more adaptable to change and easier to maintain, ultimately leading to more robust and scalable software solutions.