Polymorphism Techniques
Understanding Polymorphism
Polymorphism allows objects of different classes to be treated as objects of a common base class. It enables more flexible and extensible code design.
Types of Polymorphism
1. Method Overriding
class Animal:
def speak(self):
print("Animal makes a sound")
class Dog(Animal):
def speak(self):
print("Dog barks")
class Cat(Animal):
def speak(self):
print("Cat meows")
def animal_sound(animal):
animal.speak()
## Polymorphic behavior
dog = Dog()
cat = Cat()
animal_sound(dog) ## Output: Dog barks
animal_sound(cat) ## Output: Cat meows
2. Duck Typing
class Duck:
def swim(self):
print("Duck swimming")
def fly(self):
print("Duck flying")
class Airplane:
def fly(self):
print("Airplane flying")
def perform_flight(obj):
obj.fly()
## Different objects can be used interchangeably
duck = Duck()
airplane = Airplane()
perform_flight(duck)
perform_flight(airplane)
Polymorphism Visualization
classDiagram
Shape <|-- Circle
Shape <|-- Rectangle
Shape : +calculate_area()
Circle : +calculate_area()
Rectangle : +calculate_area()
Polymorphism Techniques
| Technique |
Description |
Example |
| Method Overriding |
Redefine methods in subclasses |
Changing speak() method |
| Duck Typing |
Use objects based on their methods |
fly() method |
| Interfaces |
Define common method signatures |
Abstract base classes |
3. Abstract Base Classes
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def calculate_area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def calculate_area(self):
return 3.14 * self.radius ** 2
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def calculate_area(self):
return self.width * self.height
def print_area(shape):
print(f"Area: {shape.calculate_area()}")
## Polymorphic behavior
circle = Circle(5)
rectangle = Rectangle(4, 6)
print_area(circle)
print_area(rectangle)
Advanced Polymorphism
Multiple Dispatch
class MathOperations:
def add(self, a, b):
return a + b
def add(self, a, b, c):
return a + b + c
## Note: Python doesn't support true method overloading
## Use functools.singledispatch for similar functionality
LabEx Polymorphism Practice
In LabEx Python environments, you can experiment with various polymorphism techniques to understand their implementation and benefits.
Best Practices
- Use polymorphism to create more flexible code
- Prefer composition over inheritance
- Keep interfaces simple and focused
- Follow the Liskov Substitution Principle
Practical Example
class PaymentProcessor:
def process_payment(self, amount):
raise NotImplementedError("Subclass must implement abstract method")
class CreditCardProcessor(PaymentProcessor):
def process_payment(self, amount):
print(f"Processing ${amount} via Credit Card")
class PayPalProcessor(PaymentProcessor):
def process_payment(self, amount):
print(f"Processing ${amount} via PayPal")
def complete_transaction(processor, amount):
processor.process_payment(amount)
## Polymorphic usage
credit_card = CreditCardProcessor()
paypal = PayPalProcessor()
complete_transaction(credit_card, 100)
complete_transaction(paypal, 50)