Polymorphism

May 20, 2023

Polymorphism is a concept in object-oriented programming that allows objects of different classes to be treated as if they were of the same class. This enables a single interface to be used to represent multiple types of objects, simplifying code and making it more flexible.

In simpler terms, polymorphism is the ability of an object to take on many forms. This means that a single object can be used to represent multiple types of objects, depending on the context in which it is used. For example, a square can be considered a type of rectangle, so you can use a square object as if it were a rectangle object.

Polymorphism is achieved in object-oriented programming through two mechanisms: inheritance and interfaces.

Inheritance

Inheritance is a mechanism in which one class inherits the properties and methods of another class. The class that inherits the properties and methods is known as the subclass or derived class, while the class that is being inherited from is known as the superclass or base class.

The subclass can override the methods of the superclass or add its own methods, while still being able to use the methods of the superclass. This allows the subclass to behave in a way that is specific to its own needs, while still inheriting the general behavior of the superclass.

For example, consider a class hierarchy that includes a superclass called “Animal” and a subclass called “Dog”. The Animal class might have a method called “eat”, which is used to describe how animals in general eat. The Dog class might override this method to describe how dogs specifically eat, while still inheriting the basic eating behavior of all animals.

class Animal:
    def eat(self):
        print("Animals eat food.")

class Dog(Animal):
    def eat(self):
        print("Dogs eat meat.")

In this example, the Dog class inherits the “eat” method from the Animal class, but overrides it to provide its own implementation.

Interfaces

An interface is a contract between a class and the code that uses it. It defines a set of methods that the class must implement, but does not provide any implementation details.

Interfaces allow objects of different classes to be treated as if they were of the same class, as long as they implement the same interface. This makes it possible to write code that is more general and flexible.

For example, consider an interface called “Drawable” that defines a method called “draw”. Any class that implements this interface must provide its own implementation of the “draw” method.

class Drawable:
    def draw(self):
        pass  # This method must be implemented by any class that implements the Drawable interface.

Now consider two classes, “Circle” and “Rectangle”, that implement the Drawable interface. They must both provide their own implementation of the “draw” method, but can be treated as if they were of the same class when being drawn.

class Circle(Drawable):
    def draw(self):
        print("Drawing a circle.")

class Rectangle(Drawable):
    def draw(self):
        print("Drawing a rectangle.")

In this example, the Circle and Rectangle classes both implement the “draw” method, which allows them to be treated as if they were of the same type when being drawn.

Benefits of Polymorphism

Polymorphism offers several benefits in object-oriented programming:

Code Reusability

Polymorphism allows code to be reused more easily by enabling objects to be treated as if they were of different types. This reduces the amount of code that needs to be written, and makes it easier to maintain and update code over time.

Flexibility

Polymorphism makes code more flexible by allowing objects to be treated as if they were of different types. This makes it possible to write code that is more general and can be used in a wider variety of contexts.

Extensibility

Polymorphism makes it easier to extend existing code by allowing new classes to be created that implement existing interfaces or inherit from existing classes. This reduces the need to rewrite existing code, and makes it easier to add new functionality to an application over time.

Examples of Polymorphism

Here are some examples of how polymorphism can be used in object-oriented programming:

Example 1: Animal Sounds

Consider a class hierarchy that includes a superclass called “Animal” and several subclasses that represent different types of animals. Each subclass should be able to make its own sound when asked to do so.

class Animal:
    def make_sound(self):
        pass  # This method must be implemented by any class that inherits from Animal.

class Dog(Animal):
    def make_sound(self):
        print("Woof!")

class Cat(Animal):
    def make_sound(self):
        print("Meow!")

class Cow(Animal):
    def make_sound(self):
        print("Moo!")

In this example, each animal subclass implements its own version of the “make_sound” method, which allows them to make their own sound when asked to do so.

dog = Dog()
cat = Cat()
cow = Cow()

dog.make_sound()  # Output: Woof!
cat.make_sound()  # Output: Meow!
cow.make_sound()  # Output: Moo!

Example 2: Shapes

Consider a program that draws different shapes on a canvas. Each shape should have its own drawing method that can be called when the shape is added to the canvas.

class Shape:
    def draw(self):
        pass  # This method must be implemented by any class that inherits from Shape.

class Circle(Shape):
    def draw(self):
        print("Drawing a circle.")

class Rectangle(Shape):
    def draw(self):
        print("Drawing a rectangle.")

class Triangle(Shape):
    def draw(self):
        print("Drawing a triangle.")

In this example, each shape subclass implements its own version of the “draw” method, which allows them to be drawn in their own unique way.

circle = Circle()
rectangle = Rectangle()
triangle = Triangle()

shapes = [circle, rectangle, triangle]

for shape in shapes:
    shape.draw()

This code will output:

Drawing a circle.
Drawing a rectangle.
Drawing a triangle.

Example 3: Sorting

Consider a program that sorts a list of objects based on a common property, such as their size.

class Object:
    def __init__(self, size):
        self.size = size

class Box(Object):
    pass

class Ball(Object):
    pass

objects = [Box(10), Ball(5), Box(5), Ball(10)]

sorted_objects = sorted(objects, key=lambda obj: obj.size)

for obj in sorted_objects:
    print(obj.size)

In this example, each object subclass inherits from the Object class, which has a common “size” property. The sorted() function is used to sort the objects based on their size, regardless of their specific subclass.

This code will output:

5
5
10
10

Overall, polymorphism is an essential concept in object-oriented programming that every developer should understand and use to create better software.