Polymorphism in Python

Loading

Polymorphism is one of the fundamental concepts of Object-Oriented Programming (OOP) that allows different classes to define methods with the same name but different behaviors.

Why Use Polymorphism?

Code Flexibility – Write generic code that works with multiple object types
Code Reusability – Use the same method name for different operations
Extensibility – Easily extend functionality without modifying existing code


1. What is Polymorphism?

Polymorphism means “many forms.” It allows the same method or function to behave differently based on the object calling it.

Example of Polymorphism

class Dog:
def sound(self):
return "Bark"

class Cat:
def sound(self):
return "Meow"

# Function demonstrating polymorphism
def animal_sound(animal):
print(animal.sound())

dog = Dog()
cat = Cat()

animal_sound(dog) # Output: Bark
animal_sound(cat) # Output: Meow

How does this work?

Even though Dog and Cat have different implementations of sound(), the same function animal_sound() works for both.


2. Types of Polymorphism in Python

Python supports three types of polymorphism:

  1. Method Overriding (Runtime Polymorphism)
  2. Method Overloading (Compile-Time Polymorphism, simulated in Python)
  3. Operator Overloading

3. Method Overriding (Runtime Polymorphism)

Method overriding allows a child class to redefine a method from the parent class.

Example: Method Overriding

class Animal:
def sound(self):
return "Some sound"

class Dog(Animal):
def sound(self): # Overriding parent method
return "Bark"

class Cat(Animal):
def sound(self): # Overriding parent method
return "Meow"

# Using overridden methods
dog = Dog()
cat = Cat()

print(dog.sound()) # Output: Bark
print(cat.sound()) # Output: Meow

Key Points:

  • The method sound() is defined in the parent class but overridden in the child classes.
  • The method in the child class replaces the parent class method when called from an instance of the child class.

4. Method Overloading (Simulated in Python)

Python does not support method overloading (same method name with different parameters) like Java or C++, but it can be simulated using default arguments or *args.

Example: Simulating Method Overloading

class MathOperations:
def add(self, a, b, c=0): # Default value allows different numbers of arguments
return a + b + c

math_obj = MathOperations()
print(math_obj.add(2, 3)) # Output: 5
print(math_obj.add(2, 3, 4)) # Output: 9

Key Points:

  • Python allows default arguments to mimic method overloading.
  • We use c=0 as a default argument to handle different cases.
  • Another way to achieve this is with *args (variable-length arguments).

Example: Using *args for Method Overloading

class Calculator:
def add(self, *args): # Accepts any number of arguments
return sum(args)

calc = Calculator()
print(calc.add(2, 3)) # Output: 5
print(calc.add(2, 3, 4, 5)) # Output: 14

Advantage: Works for any number of arguments.


5. Operator Overloading in Python

Operator overloading allows operators (+, -, *, etc.) to be redefined for custom objects.

Example: Operator Overloading with +

class Point:
def __init__(self, x, y):
self.x = x
self.y = y

def __add__(self, other): # Overloading "+"
return Point(self.x + other.x, self.y + other.y)

def __str__(self):
return f"({self.x}, {self.y})"

p1 = Point(2, 3)
p2 = Point(4, 5)

result = p1 + p2 # Calls __add__()
print(result) # Output: (6, 8)

Key Points:

  • __add__() defines how + works for Point objects.
  • p1 + p2 calls p1.__add__(p2).
  • Similar methods exist for - (__sub__), * (__mul__), and / (__truediv__).

6. Polymorphism with Abstract Classes (Using abc Module)

Abstract classes enforce that subclasses must implement certain methods.

from abc import ABC, abstractmethod

class Animal(ABC): # Abstract class
@abstractmethod
def sound(self):
pass # Must be implemented in child classes

class Dog(Animal):
def sound(self):
return "Bark"

class Cat(Animal):
def sound(self):
return "Meow"

dog = Dog()
cat = Cat()

print(dog.sound()) # Output: Bark
print(cat.sound()) # Output: Meow

Key Points:

  • ABC (Abstract Base Class) ensures sound() must be implemented in subclasses.
  • If a subclass does not implement sound(), it raises an error.

7. Real-World Example: Payment System

class Payment:
def process_payment(self, amount):
pass # Placeholder for child classes

class CreditCardPayment(Payment):
def process_payment(self, amount):
print(f"Processing credit card payment of ${amount}")

class PayPalPayment(Payment):
def process_payment(self, amount):
print(f"Processing PayPal payment of ${amount}")

# Function using polymorphism
def make_payment(payment_method, amount):
payment_method.process_payment(amount)

cc = CreditCardPayment()
paypal = PayPalPayment()

make_payment(cc, 100) # Output: Processing credit card payment of $100
make_payment(paypal, 50) # Output: Processing PayPal payment of $50

Key Points:

  • make_payment() works with any Payment subclass, enabling polymorphism.
  • Easily extendable by adding new payment methods without modifying existing code.

Leave a Reply

Your email address will not be published. Required fields are marked *