Inheritance Types in Python

Module 3 • Session 25 • OOP Reuse, super(), Method Resolution Order (MRO) & Design Patterns

inheritance super() MRO method-overriding c3-linearization

Inheritance is a cornerstone of Object-Oriented Programming that allows a class (child/derived class) to acquire attributes and methods from another class (parent/base class). It promotes code reusability, modular architecture, and hierarchical modeling while enabling method overriding and dynamic behavior delegation.

1. Core Concepts: The `super()` Function & Method Overriding

- **Method Overriding:** Occurs when a child class defines a method with the same name as one in its parent class, replacing or extending the base implementation.
- **`super()` Delegation:** The super() proxy object delegates method calls to parent or sibling classes based on the class hierarchy, avoiding explicit hardcoded references to base class names.

class Animal: def __init__(self, name): self.name = name def speak(self): return f"{self.name} makes a generic sound." class Dog(Animal): def __init__(self, name, breed): # Pass initialization to the parent class via super() super().__init__(name) self.breed = breed def speak(self): # Override parent method while referencing base behavior if needed base_sound = super().speak() return f"{base_sound} Specifically, {self.name} barks!" d = Dog("Rex", "German Shepherd") print(d.speak())

2. Five Primary Types of Inheritance

A. Single Inheritance

A child class inherits from a single base class.

class Parent: def feature_parent(self): print("Parent feature") class Child(Parent): def feature_child(self): print("Child feature")

B. Multilevel Inheritance

A child class inherits from a derived class, forming a chain (Grandparent > Parent > Child).

class Vehicle: category = "Land Vehicle" class Car(Vehicle): wheels = 4 class ElectricCar(Car): battery_type = "Lithium-ion" ec = ElectricCar() print(ec.category, ec.wheels, ec.battery_type)

C. Hierarchical Inheritance

Multiple child classes inherit from the same single base class.

class Shape: def draw(self): print("Drawing shape...") class Circle(Shape): def draw(self): print("Drawing Circle") class Square(Shape): def draw(self): print("Drawing Square")

D. Multiple Inheritance

A child class inherits directly from more than one base class.

class Flyer: def fly(self): return "Flying high" class Swimmer: def swim(self): return "Swimming fast" class Duck(Flyer, Swimmer): pass d = Duck() print(d.fly(), "and", d.swim())

E. Hybrid Inheritance

A combination of two or more inheritance patterns (e.g., Multiple + Multilevel), often producing a diamond structural pattern.

3. Method Resolution Order (MRO) & C3 Linearization

When dealing with multiple or hybrid inheritance, Python resolves attribute lookups through **Method Resolution Order (MRO)** powered by the **C3 Linearization algorithm**. This guarantees that base classes are evaluated in a consistent, left-to-right, depth-first without duplication order.

Inspecting MRO: You can view any class's resolution order by calling ClassName.mro() or inspecting ClassName.__mro__.
class A: def process(self): print("A process") class B(A): def process(self): print("B process") super().process() class C(A): def process(self): print("C process") super().process() class D(B, C): def process(self): print("D process") super().process() # MRO for class D: D -> B -> C -> A -> object print("MRO for D:", [cls.__name__ for cls in D.mro()]) d = D() d.process() # Output order: D process -> B process -> C process -> A process

4. Comparison Matrix of Inheritance Models

Inheritance Type Parent Classes Child Classes Primary Use Case
Single 1 Base Class 1 Derived Class Direct specialized extension of base logic.
Multilevel 1 Base per step Chain of Derived Classes Sequential refinement across abstraction layers.
Hierarchical 1 Base Class Multiple Derived Classes Shared foundation extended into distinct implementations.
Multiple Multiple Bases 1 Derived Class Combining orthogonal behaviors (Mixin patterns).
Hybrid Mixed Structure Mixed Structure Complex enterprise domain modeling combining mixins & chains.
Avoid the Diamond Trap: Ensure cooperative call chains by using super() consistently across all classes in a multiple/hybrid inheritance hierarchy rather than calling parent methods by hardcoded name!

5. Real-World Enterprise Scenario: Payment Gateway Pipeline

This example demonstrates multiple inheritance using Mixins to add audit logging and encryption functionality to base payment processors.

class AuditLoggerMixin: def log_transaction(self, tx_id, amount): print(f"[AUDIT LOG] Tx:{tx_id} | Amount:${amount:.2f} logged successfully.") class EncryptionMixin: def encrypt_payload(self, data): return f"ENC({data[::-1]})" class BasePaymentProcessor: def __init__(self, merchant_id): self.merchant_id = merchant_id def process(self, amount): raise NotImplementedError("Subclasses must implement process()") class SecureStripeProcessor(BasePaymentProcessor, AuditLoggerMixin, EncryptionMixin): def __init__(self, merchant_id, api_key): super().__init__(merchant_id) self.api_key = api_key def process(self, amount): tx_id = "TX_994812" encrypted_key = self.encrypt_payload(self.api_key) print(f"Processing Stripe payment with key token {encrypted_key}...") self.log_transaction(tx_id, amount) return True stripe = SecureStripeProcessor("MERCHANT_88", "secret_stripe_token_123") stripe.process(150.75)

🏋️ Try It Yourself: Practice Challenges

Challenge 1: Single & Multilevel Chain

Build a Person base class, an Employee derived class, and a Manager subclass. Demonstrate proper super().__init__() initialization through all 3 tiers.

Challenge 2: Mixin Architecture

Create a JSONSerializerMixin with a method to_json() that converts self.__dict__ to a JSON string, and apply it to a User class via multiple inheritance.

Challenge 3: MRO Tracing

Define a diamond hierarchy (Classes A, B(A), C(A), D(B,C)). Print D.mro() and trace the execution order when invoking a method shared across all nodes.

⚡ Interactive Sandbox (Inheritance & MRO)
Console Output:
Click "Run Code" above to execute scripts...

📝 Knowledge Check Quiz

1. What algorithm does CPython use to compute the Method Resolution Order (MRO)?
2. Why is using `super()` preferred over hardcoding `BaseClass.method(self)` inside child methods?
3. What pattern describes inheriting from a class that inherits from another class (A > B > C)?
Advertisement
Horizontal Ad Banner Slot (728x90 / Responsive)