What is Polymorphism in Python?

Polymorphism is a core concept of Object-Oriented Programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. The key idea behind polymorphism is that the same method or operation can have different meanings depending on the object that invokes it.



Types of Polymorphism in Python

  • Compile-Time Polymorphism (Static Polymorphism): Occurs when the method to be executed is determined at compile-time. This is usually achieved through method overloading, though Python does not directly support method overloading.
  • Run-Time Polymorphism (Dynamic Polymorphism): Occurs when the method to be executed is determined at runtime. This is typically achieved using method overriding.


Example 1: Method Overriding and Run-Time Polymorphism

class Animal:
    def sound(self):
        print("Animal makes a sound")

class Dog(Animal):
    def sound(self):
        print("Dog barks")

class Cat(Animal):
    def sound(self):
        print("Cat meows")

# Polymorphism in action
def make_sound(animal):
    animal.sound()

# Creating objects of different types
a = Animal()
d = Dog()
c = Cat()

make_sound(a)  # Animal makes a sound
make_sound(d)  # Dog barks
make_sound(c)  # Cat meows

Output:

Animal makes a sound
Dog barks
Cat meows

Why Polymorphism is Important in Python?

  • Code Reusability: You can use the same interface (method name) across different classes and allow the objects to use their own version of the method.
  • Flexibility: It allows for flexibility in the code and makes it easier to add new functionalities.


Example 2: Using Method Overloading in Python (Simulated)

Since Python does not support method overloading directly, you can achieve it by using default arguments or *args / **kwargs.

class Calculator:
    def add(self, a, b=0, c=0):
        return a + b + c

calc = Calculator()
print(calc.add(2))        # Single argument
print(calc.add(2, 3))     # Two arguments
print(calc.add(2, 3, 4))  # Three arguments

Output:

2
5
9


Example 3: Polymorphism with Different Methods

class Shape:
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius * self.radius

class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side * self.side

# Polymorphism in action
shapes = [Circle(5), Square(4)]

for shape in shapes:
    print(f"Area: {shape.area()}")

Output:

Area: 78.5
Area: 16


Real-Life Analogy of Polymorphism

Imagine you have a remote control that can operate various devices like TVs, Air conditioners, or fans. The remote control has a turn_on() method, but each device has its own way of implementing it. This is similar to how polymorphism works: the same method (turn_on()) behaves differently based on the object (device) it's called on.