In Object-Oriented Programming, polymorphism means “many forms”—the ability of a method, object, or operator to behave differently in different contexts. Python supports both compile-time polymorphism and runtime polymorphism, although the way it implements them is slightly different due to Python being a dynamically typed language.
1. Compile-Time Polymorphism (Static Polymorphism) #
- Definition: The method call or operator resolution happens at compile-time.
- Achieved by: Method overloading or operator overloading.
- Characteristics:
- Determined by the number or type of arguments (in languages like C++/Java).
- Faster, but less flexible.
Python Note:
Python does not support true method overloading like Java, but you can simulate it using default arguments or *args/**kwargs.
Example (simulated overloading in Python):
class Calculator:
def add(self, a, b=0, c=0):
return a + b + c
calc = Calculator()
print(calc.add(5)) # 5
print(calc.add(5, 10)) # 15
print(calc.add(5, 10, 20)) # 35
Here, the add method behaves differently depending on how many arguments are passed—simulating compile-time polymorphism.
2. Runtime Polymorphism (Dynamic Polymorphism) #
- Definition: The method call is resolved at runtime based on the actual object type.
- Achieved by: Method overriding (child class providing a new implementation of a parent class method).
- Characteristics:
- Supports inheritance and polymorphism.
- Flexible, allows dynamic behavior at runtime.
Example:
class Employee:
def work(self):
print("Employee working")
class Manager(Employee):
def work(self): # overrides work
print("Manager managing team")
def start_work(emp):
emp.work() # Resolved at runtime
e = Employee()
m = Manager()
start_work(e) # Employee working
start_work(m) # Manager managing team
Here, emp.work() is dynamically bound to the actual object type at runtime.
Key Differences #
| Feature | Compile-Time Polymorphism | Runtime Polymorphism |
|---|---|---|
| Binding | Static / Early binding | Dynamic / Late binding |
| When resolved | Compile-time | Runtime |
| Method type | Overloading / operator overloading | Overriding |
| Flexibility | Less flexible | More flexible |
| Python Support | Simulated using *args/default args | Fully supported (overriding) |
Practical Use Case #
- Compile-time polymorphism: Calculator or utility functions that accept varying numbers of inputs.
- Runtime polymorphism: Reporting system where
generate_report()behaves differently inMonthlyReport,AnnualReport, orCustomReportsubclasses. This allows a consistent interface while handling multiple report types dynamically.
