
Python
Polymorphism means "many forms." It allows you to write code that works with objects of different types through a common interface. Polymorphism makes your code flexible and extensible—you can add new types without changing existing code.
Polymorphism allows different objects to respond to the same method call in their own way. You can write code that treats multiple different types uniformly, and each object responds according to its own implementation.
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow!"
class Bird:
def speak(self):
return "Tweet!"
# Polymorphism in action - same method, different behavior
animals = [Dog(), Cat(), Bird()]
for animal in animals:
print(animal.speak()) # Each responds differently
# Output:
# Woof!
# Meow!
# Tweet!The most common way to achieve polymorphism is through method overriding. Different child classes override the same method with different implementations.
class Shape:
def area(self):
pass # Base implementation
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Triangle(Shape):
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
return 0.5 * self.base * self.height
# Polymorphic function
def print_area(shape):
print(f"Area: {shape.area()}")
# Works with any shape
shapes = [Circle(5), Rectangle(4, 6), Triangle(3, 4)]
for shape in shapes:
print_area(shape)
# Output:
# Area: 78.5
# Area: 24
# Area: 6.0Write functions that accept any object with the required methods. The function doesn't need to know the exact type—it just calls the method and the object responds appropriately.
class Guitar:
def play(self):
return "Strumming a guitar... Twang!"
class Piano:
def play(self):
return "Playing piano... Plink plink!"
class Violin:
def play(self):
return "Playing violin... Screech!"
# Function works with any object that has a play() method
def perform_concert(musicians):
for musician in musicians:
print(musician.play())
# Create different instruments
band = [Guitar(), Piano(), Violin(), Guitar()]
perform_concert(band)
# Output:
# Strumming a guitar... Twang!
# Playing piano... Plink plink!
# Playing violin... Screech!
# Strumming a guitar... Twang!Python uses "duck typing"—if an object has the required methods, it can be used. You don't need to formally declare that a class inherits from another. This makes Python very flexible.
class Printer:
def print_document(self, document):
return f"Printing: {document}"
class DigitalDisplay:
def print_document(self, document):
return f"Displaying: {document}"
class Speaker:
def print_document(self, document):
return f"Speaking: {document}"
# Function doesn't care about class hierarchy
def handle_document(device, doc):
return device.print_document(doc)
# Works with any object that has print_document method
printer = Printer()
display = DigitalDisplay()
speaker = Speaker()
print(handle_document(printer, "Letter"))
print(handle_document(display, "Slide"))
print(handle_document(speaker, "Instructions"))Polymorphism shines when working with lists of different object types. Process them all uniformly.
class Employee:
def work(self):
pass
def get_salary(self):
pass
class Manager(Employee):
def __init__(self, name, salary):
self.name = name
self.salary = salary
def work(self):
return f"{self.name} manages the team"
def get_salary(self):
return self.salary
class Developer(Employee):
def __init__(self, name, salary, language):
self.name = name
self.salary = salary
self.language = language
def work(self):
return f"{self.name} codes in {self.language}"
def get_salary(self):
return self.salary
class Intern(Employee):
def __init__(self, name, salary):
self.name = name
self.salary = salary
def work(self):
return f"{self.name} learns and assists"
def get_salary(self):
return self.salary
# Process all employees uniformly
employees = [
Manager("Alice", 100000),
Developer("Bob", 80000, "Python"),
Developer("Charlie", 75000, "JavaScript"),
Intern("Diana", 30000)
]
total_payroll = 0
for emp in employees:
print(emp.work())
total_payroll += emp.get_salary()
print(f"\nTotal payroll: ${total_payroll}")class PaymentMethod:
def process_payment(self, amount):
pass
class CreditCard(PaymentMethod):
def __init__(self, card_number):
self.card_number = card_number
def process_payment(self, amount):
return f"Processing ${amount} with credit card {self.card_number[-4:]}"
class PayPal(PaymentMethod):
def __init__(self, email):
self.email = email
def process_payment(self, amount):
return f"Processing ${amount} via PayPal ({self.email})"
class Bitcoin(PaymentMethod):
def __init__(self, wallet):
self.wallet = wallet
def process_payment(self, amount):
return f"Processing ${amount} in Bitcoin to {self.wallet}"
class CheckoutSystem:
def __init__(self, payment_method):
self.payment_method = payment_method
def checkout(self, amount):
return self.payment_method.process_payment(amount)
# Use any payment method
card = CreditCard("4532-1234-5678-9010")
paypal = PayPal("user@example.com")
bitcoin = Bitcoin("1A1z7agoat4...")
checkout1 = CheckoutSystem(card)
print(checkout1.checkout(99.99))
checkout2 = CheckoutSystem(paypal)
print(checkout2.checkout(99.99))
checkout3 = CheckoutSystem(bitcoin)
print(checkout3.checkout(99.99))class Vehicle:
def __init__(self, make, model, daily_rate):
self.make = make
self.model = model
self.daily_rate = daily_rate
def calculate_rental_cost(self, days):
pass
def get_info(self):
pass
class Car(Vehicle):
def calculate_rental_cost(self, days):
return self.daily_rate * days
def get_info(self):
return f"Car: {self.make} {self.model}"
class Truck(Vehicle):
def __init__(self, make, model, daily_rate, tonnage):
super().__init__(make, model, daily_rate)
self.tonnage = tonnage
def calculate_rental_cost(self, days):
return self.daily_rate * days * 1.5 # 50% more for trucks
def get_info(self):
return f"Truck: {self.make} {self.model} ({self.tonnage} ton)"
class Motorcycle(Vehicle):
def calculate_rental_cost(self, days):
return self.daily_rate * days * 0.6 # 40% less for bikes
def get_info(self):
return f"Motorcycle: {self.make} {self.model}"
# Rental fleet with different vehicles
fleet = [
Car("Toyota", "Camry", 50),
Truck("Ford", "F-150", 75, 2),
Motorcycle("Harley", "Davidson", 40),
Car("Honda", "Civic", 45)
]
rental_days = 3
total_revenue = 0
for vehicle in fleet:
cost = vehicle.calculate_rental_cost(rental_days)
total_revenue += cost
print(f"{vehicle.get_info()} - {rental_days} days: ${cost}")
print(f"\nTotal revenue: ${total_revenue}")| Concept | Remember |
|---|---|
| Polymorphism | Objects of different types respond to same method differently |
| Method Overriding | Child classes provide their own implementation of parent methods |
| Common Interface | Different types expose the same method names |
| Flexibility | Write code once that works with multiple types |
| Duck Typing | If it walks and quacks like a duck, use it as a duck |
| Extensibility | Add new types without changing existing code |
| Type Independence | Code doesn't need to know exact object type |
Now let's learn about encapsulation, which helps you control how data is accessed and modified.
Ready to practice? Try challenges or explore more concepts
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward