Python - Inheritance
Overview
Estimated time: 25–35 minutes
Use inheritance to reuse behavior and specialize subclasses. Learn when to prefer composition.
Learning Objectives
- Define base and derived classes; override methods.
- Use super()to delegate to parent implementations.
- Choose composition over inheritance when appropriate.
Prerequisites
Basic inheritance
class Shape:
    def area(self) -> float:
        return 0.0
class Rectangle(Shape):
    def __init__(self, w: float, h: float):
        self.w = w; self.h = h
    def area(self) -> float:
        return self.w * self.h
print(Rectangle(3, 4).area())
Using super()
class Logger:
    def log(self, msg: str) -> None:
        print(f"LOG: {msg}")
class TimestampLogger(Logger):
    def log(self, msg: str) -> None:
        from datetime import datetime
        super().log(f"{datetime.now().isoformat()} - {msg}")
TimestampLogger().log("hello")
Composition over inheritance
class Service:
    def __init__(self, logger: Logger):
        self.logger = logger
    def run(self):
        self.logger.log("running")
Service(TimestampLogger()).run()
Common Pitfalls
- Deep inheritance hierarchies; prefer shallow trees and clear responsibilities.
- Forgetting to call super().__init__in cooperative multiple inheritance.
Checks for Understanding
- What does super()do?
- When might composition be a better fit than inheritance?
Show answers
- It delegates to the next method in the MRO, typically the parent implementation.
- When you want to reuse behavior without creating an "is-a" relationship.
Exercises
- Create an Employeebase class and aManagersubclass that overrides a method.
- Refactor an inheritance use into composition and compare readability.