PYTHON POLYMORPHISM

Learn how polymorphism allows the same method, function, or operation to behave differently depending on the object being used, with practical real-time Python examples.

What is Polymorphism?

Polymorphism means "many forms." In Python, polymorphism allows the same interface, method, or operation to work with different types of objects.

The same method name can perform different actions depending on the object that calls it. This makes programs flexible, reusable, and easier to extend.

Same Method
→
Different Objects
→
Different Behavior

Method Overriding

Different child classes can provide their own implementation of the same method.

Duck Typing

Python focuses on what an object can do rather than its exact class type.

Operator Overloading

Operators such as +, *, and == can behave differently for different objects.

Function Polymorphism

The same function can work with different types of objects or data.

1. Basic Polymorphism Example

Different classes can have a method with the same name, but each class can implement that method differently.

Python Code
class Dog:
    def sound(self):
        print("Dog says: Woof!")


class Cat:
    def sound(self):
        print("Cat says: Meow!")


dog = Dog()
cat = Cat()

dog.sound()
cat.sound()
Output:
Dog says: Woof!
Cat says: Meow!

Both objects use the same sound() method name, but the behavior is different.

2. Polymorphism with Inheritance

Polymorphism is commonly used with inheritance. A parent class defines a common method, and child classes override it with their own behavior.

Python Code
class Employee:
    def work(self):
        print("Employee is working")


class Developer(Employee):
    def work(self):
        print("Developer is writing code")


class Designer(Employee):
    def work(self):
        print("Designer is creating designs")


developer = Developer()
designer = Designer()

developer.work()
designer.work()
Output:
Developer is writing code
Designer is creating designs

The same work() method behaves differently for each child object.

3. Real-Time Example: Payment System

In a payment application, different payment methods can provide their own implementation of a common pay() method.

Python Code
class CreditCard:
    def pay(self, amount):
        print("Paid", amount, "using Credit Card")


class UPI:
    def pay(self, amount):
        print("Paid", amount, "using UPI")


class NetBanking:
    def pay(self, amount):
        print("Paid", amount, "using Net Banking")


payments = [
    CreditCard(),
    UPI(),
    NetBanking()
]

for payment in payments:
    payment.pay(2500)
Output:
Paid 2500 using Credit Card
Paid 2500 using UPI
Paid 2500 using Net Banking

The loop does not need to know the exact class of each payment object. It simply calls pay().

4. Real-Time Example: Notification System

A notification system may send messages through email, SMS, or push notifications. Each class can implement send() differently.

Python Code
class EmailNotification:
    def send(self, message):
        print("Email:", message)


class SMSNotification:
    def send(self, message):
        print("SMS:", message)


class PushNotification:
    def send(self, message):
        print("Push Notification:", message)


notifications = [
    EmailNotification(),
    SMSNotification(),
    PushNotification()
]

for notification in notifications:
    notification.send("Your order has been shipped.")
Output:
Email: Your order has been shipped.
SMS: Your order has been shipped.
Push Notification: Your order has been shipped.
5. Duck Typing in Python

Python follows the idea of duck typing: "If it behaves like the required object, it can be used."

Python Code
class Duck:
    def fly(self):
        print("Duck is flying")


class Bird:
    def fly(self):
        print("Bird is flying")


class Airplane:
    def fly(self):
        print("Airplane is flying")


def make_it_fly(obj):
    obj.fly()


make_it_fly(Duck())
make_it_fly(Bird())
make_it_fly(Airplane())
Output:
Duck is flying
Bird is flying
Airplane is flying

The function does not check the object's class. It only expects the object to provide a fly() method.

6. Polymorphism with Functions

A single function can work with different objects as long as those objects support the required operation.

Python Code
def calculate_total(a, b):
    return a + b


print(calculate_total(10, 20))
print(calculate_total(10.5, 20.5))
print(calculate_total("Hello ", "Python"))
Output:
30
31.0
Hello Python

The + operation works differently depending on the data type: numbers are added while strings are concatenated.

7. Operator Polymorphism

Python operators can perform different operations depending on the types of objects involved.

Python Code
print(10 + 20)

print("Python " + "Programming")

print([1, 2] + [3, 4])

print(5 * 3)

print("Hi " * 3)
Output:
30
Python Programming
[1, 2, 3, 4]
15
Hi Hi Hi

The same operators can have different meanings for different Python data types.

8. Method Overriding with super()

A child class can override a parent method while still calling the original parent implementation using super().

Python Code
class Employee:
    def work(self):
        print("Employee is working")


class Developer(Employee):
    def work(self):
        super().work()
        print("Developer is writing Python code")


developer = Developer()

developer.work()
Output:
Employee is working
Developer is writing Python code
9. Real-Time Example: Vehicle System

Different vehicles can implement the same start() method according to their own behavior.

Python Code
class Car:
    def start(self):
        print("Car engine started")


class Bike:
    def start(self):
        print("Bike engine started")


class ElectricCar:
    def start(self):
        print("Electric motor started")


vehicles = [
    Car(),
    Bike(),
    ElectricCar()
]

for vehicle in vehicles:
    vehicle.start()
Output:
Car engine started
Bike engine started
Electric motor started
10. Real-Time Example: Employee Payroll

Different types of employees may calculate their salary differently while exposing the same calculate_salary() method.

Python Code
class FullTimeEmployee:
    def calculate_salary(self):
        return 60000


class PartTimeEmployee:
    def calculate_salary(self):
        return 30000


class ContractEmployee:
    def calculate_salary(self):
        return 45000


employees = [
    FullTimeEmployee(),
    PartTimeEmployee(),
    ContractEmployee()
]

for employee in employees:
    print("Salary:", employee.calculate_salary())
Output:
Salary: 60000
Salary: 30000
Salary: 45000
11. Real-Time Example: E-Commerce Products

Different product types can calculate discounts using the same method name.

Python Code
class Electronics:
    def discount(self, price):
        return price * 0.10


class Clothing:
    def discount(self, price):
        return price * 0.20


class Grocery:
    def discount(self, price):
        return price * 0.05


products = [
    Electronics(),
    Clothing(),
    Grocery()
]

price = 10000

for product in products:
    print("Discount:", product.discount(price))
Output:
Discount: 1000.0
Discount: 2000.0
Discount: 500.0
12. Real-Time Example: Shape Area

Different shapes can implement the same area() method while using different formulas.

Python Code
class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width


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

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


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

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


shapes = [
    Rectangle(10, 5),
    Circle(7),
    Square(6)
]

for shape in shapes:
    print("Area:", shape.area())
Output:
Area: 50
Area: 153.86
Area: 36

The loop simply calls area(). Each object calculates the result using its own implementation.

13. Real-Time Example: Food Ordering System

Different food items can implement a common prepare() method.

Python Code
class Pizza:
    def prepare(self):
        print("Preparing Pizza")


class Burger:
    def prepare(self):
        print("Preparing Burger")


class Biryani:
    def prepare(self):
        print("Preparing Biryani")


orders = [
    Pizza(),
    Burger(),
    Biryani()
]

for order in orders:
    order.prepare()
Output:
Preparing Pizza
Preparing Burger
Preparing Biryani
14. Real-Time Example: Hospital System

Doctors, nurses, and other healthcare professionals may perform different actions through a common interface.

Python Code
class Doctor:
    def perform_duty(self):
        print("Doctor is diagnosing patients")


class Nurse:
    def perform_duty(self):
        print("Nurse is caring for patients")


class Pharmacist:
    def perform_duty(self):
        print("Pharmacist is preparing medicines")


staff = [
    Doctor(),
    Nurse(),
    Pharmacist()
]

for person in staff:
    person.perform_duty()
Output:
Doctor is diagnosing patients
Nurse is caring for patients
Pharmacist is preparing medicines
15. Operator Overloading with __add__()

Python allows classes to define how operators behave for their objects. This is called operator overloading.

Python Code
class Product:
    def __init__(self, price):
        self.price = price

    def __add__(self, other):
        return self.price + other.price


product1 = Product(1000)
product2 = Product(1500)

total = product1 + product2

print("Total Price:", total)
Output:
Total Price: 2500

The + operator is customized using the special method __add__().

16. Complete Real-Time Example: Notification Application

This example combines inheritance and polymorphism in a simple notification system.

Python Code
class Notification:
    def send(self, message):
        print("Sending notification:", message)


class EmailNotification(Notification):
    def send(self, message):
        print("Sending Email:", message)


class SMSNotification(Notification):
    def send(self, message):
        print("Sending SMS:", message)


class PushNotification(Notification):
    def send(self, message):
        print("Sending Push Notification:", message)


notifications = [
    EmailNotification(),
    SMSNotification(),
    PushNotification()
]

message = "Your order has been delivered."

for notification in notifications:
    notification.send(message)
Output:
Sending Email: Your order has been delivered.
Sending SMS: Your order has been delivered.
Sending Push Notification: Your order has been delivered.

The loop uses the same notification.send() statement for all three objects, but each object produces different behavior. This is polymorphism in practice.

17. Polymorphism vs Inheritance
Concept Purpose Example
Inheritance Reuse properties and methods from another class. Developer inherits Employee
Polymorphism Same interface produces different behavior. Developer.work() and Designer.work()
Method Overriding Child class provides its own implementation of a parent method. Developer overrides work()
Duck Typing Object capability matters more than its exact class. Any object with fly()
Operator Overloading Customize operators for user-defined objects. __add__()
18. Important Polymorphism Rules

Rule 1: Same interface, different behavior

Different objects can respond differently to the same method call.

Rule 2: Method overriding enables runtime polymorphism

Child classes can override methods inherited from their parent classes.

Rule 3: Python supports duck typing

Python generally cares about whether an object supports the required operation rather than requiring a specific class.

Rule 4: Functions can work with multiple object types

A function can accept different objects when they provide the methods or operations the function needs.

Rule 5: Operators can have multiple meanings

Operators such as + can perform different operations depending on the objects involved.

Remember: Polymorphism makes code flexible because you can write common logic once and allow different objects to provide their own behavior.