Polymorphism allows objects of different classes to respond to the same method interface. Python enforces polymorphism primarily via Duck Typing ("If it walks like a duck and quacks like a duck, it's a duck") and Abstract Base Classes (ABCs).
flowchart TD
A["Polymorphism in Python"] --> B["Duck Typing (Implicit Protocol)"]
A --> C["Abstract Base Classes abc.ABC (Explicit Contract)"]
A --> D["typing.Protocol (Structural Subtyping)"]
abc.ABC & @abstractmethod: Force derived subclasses to implement mandatory methods.typing.Protocol: Enables compile-time structural type checking (MyPy) without explicit class inheritance.from abc import ABC, abstractmethod
from typing import List
class PaymentProcessor(ABC):
"""Abstract base class defining contract for payment implementations."""
@abstractmethod
def process_payment(self, amount: float) -> bool:
pass
class StripeProcessor(PaymentProcessor):
def process_payment(self, amount: float) -> bool:
print(f"Processing ${amount:.2f} via Stripe API...")
return True
class PayPalProcessor(PaymentProcessor):
def process_payment(self, amount: float) -> bool:
print(f"Processing ${amount:.2f} via PayPal REST API...")
return True
# Polymorphic Function accepting any PaymentProcessor subclass
def checkout(processor: PaymentProcessor, order_total: float) -> None:
success = processor.process_payment(order_total)
if success:
print("Checkout completed successfully!
")
if __name__ == "__main__":
processors: List[PaymentProcessor] = [StripeProcessor(), PayPalProcessor()]
for proc in processors:
checkout(proc, 99.99)
PaymentProcessor()) directly raises TypeError..read(), don't mandate subclassing; just expect the method to exist.@abstractmethod Decorators: Always mark required interface methods with @abstractmethod inside ABC classes.Define an ABC named Shape with an @abstractmethod area(), implement a Circle(radius) subclass, and calculate its area.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With