Python Inheritance
A complete beginner-friendly guide to inheritance in Python โ covering single, multiple, multilevel, hierarchical, and hybrid inheritance, the super() function, method overriding, and Method Resolution Order (MRO) for 2026.
Last Updated
March 2026
Read Time
27 min
Level
Beginner
What is Inheritance in Python?
Inheritance is an object-oriented mechanism that lets one class acquire the attributes and methods of another class. The class being inherited from is called the parent class (or base/superclass), and the class that inherits is called the child class (or derived/subclass). Inheritance lets you build new, specialised classes on top of existing general ones, without rewriting shared logic from scratch.
Think of it like a family tree of blueprints. A general Vehicle blueprint might describe that every vehicle has a brand and can move. A more specific Car blueprint can inherit everything from Vehicle and then add its own details โ like a trunk or four doors โ without redrawing the parts it already shares with every other vehicle. This relationship is often summarised as an "is-a" relationship: a Car is a Vehicle.
In Python, inheritance is declared simply by placing the parent class name in parentheses after the child class name: class Car(Vehicle):. From that moment on, every attribute and method defined on Vehicle is automatically available on Car as well, unless Car chooses to override it with its own version.
Inheritance is one of the four foundational pillars of OOP, alongside Encapsulation, Abstraction, and Polymorphism. It is arguably the pillar most responsible for Python's reputation for code reuse โ well-designed inheritance hierarchies let large systems avoid duplicating logic across dozens of similar classes, which is a major reason frameworks like Django rely on it so heavily.
How Inheritance Evolved in Python
Inheritance has been part of Python since its very first release, but the rules governing how it resolves conflicts and interacts with the rest of the language have been refined substantially over the decades. Here is a timeline of the key milestones:
- โถ
1991 โ Python 0.9.0 already supported multiple inheritance from its earliest public release, a bold design choice that many later mainstream languages deliberately avoided.
- โถ
1995-2000 โ Early 'classic classes' resolved multiple inheritance using a simple depth-first, left-to-right search, which could produce confusing or inconsistent results in complex hierarchies.
- โถ
2001 โ Python 2.2 introduced new-style classes and, alongside them, the C3 linearisation algorithm for calculating a class's Method Resolution Order (MRO), fixing long-standing inconsistencies in multiple inheritance.
- โถ
2001 โ The super() function was introduced in the same release, initially requiring explicit arguments like super(Car, self).
- โถ
2008 โ Python 3.0 simplified super() to a zero-argument form โ just super() โ making constructor and method chaining far less verbose and error-prone.
- โถ
2015 โ PEP 484 type hints allowed inheritance relationships to be checked more rigorously by static type checkers like mypy, catching subclassing mistakes before runtime.
- โถ
2019 โ Python 3.8 introduced Protocol classes via typing.Protocol, enabling 'structural' inheritance-like behaviour (duck typing with type checking) without requiring formal class inheritance.
- โถ
2022-2026 โ Python 3.11 through 3.14 focused on faster attribute lookup across inheritance chains and continued refinement of typing.Self, making inherited method chains both faster and easier to type-check accurately.
Types of Inheritance in Python
Python supports every classic form of inheritance found in object-oriented design. Understanding each type โ and when to use it โ is essential to designing clean class hierarchies.
One child class inherits from exactly one parent class. This is the simplest and most common form, e.g. class Car(Vehicle):.
One child class inherits from more than one parent class at once, e.g. class Sedan(Car, LuxuryFeatures):. Python resolves conflicts using MRO.
A chain of inheritance across several levels, e.g. Vehicle โ Car โ SportsCar, where each class inherits from the one directly above it.
Multiple child classes all inherit from the same single parent class, e.g. Car, Truck, and Motorcycle all inheriting from Vehicle.
A combination of two or more inheritance types in one hierarchy, such as mixing hierarchical and multiple inheritance together in the same design.
Lets a child class call methods (especially __init__) from its parent class, enabling clean chaining without hard-coding the parent's class name.
A child class redefining a method that already exists in its parent, replacing the inherited behaviour with its own specialised version.
The precise order Python searches through a class hierarchy when looking up a method or attribute, calculated using the C3 linearisation algorithm.
Built-in functions for checking whether an object belongs to a class (or its subclasses), and whether one class is a subclass of another.
Classes designed to be inherited from but never instantiated directly, defined using the abc module, forcing subclasses to implement specific methods.
How Method Lookup Works Through Inheritance โ Flowchart
When you call a method on an object, Python doesn't just look at that object's own class โ it searches up through the entire inheritance chain until it finds a matching method. The flowchart below traces exactly how this search happens.
Code Execution Flow โ from source to output
Key insight: Python always uses the first matching method found, searching starting from the object's own class and moving upward through its parents in the exact order defined by the MRO. This is precisely how method overriding works โ a child class's version is found first, so it "wins" over the parent's version further up the chain.
How Python Inheritance Works โ super(), Overriding, and MRO Explained
Three concepts sit at the heart of practical Python inheritance: the super() function, method overriding, and Method Resolution Order (MRO). Understanding these three deeply is what separates a beginner who can write class Car(Vehicle): from someone who can confidently design a multi-level class hierarchy.
๐ The super() Function
super() gives a child class a way to call methods defined on its parent class, without hard-coding the parent's class name directly. It is most commonly used inside a child's __init__ to reuse the parent's initialisation logic: super().__init__(brand) runs Vehicle's constructor before Car's own constructor adds its specific attributes. Using super() instead of writing Vehicle.__init__(self, brand) directly makes code more maintainable โ if the parent class is ever renamed or the hierarchy restructured, super() automatically adapts, while a hard-coded class name would not.
๐ญ Method Overriding
Method overriding happens when a child class defines a method with the exact same name as one already defined in its parent class. The child's version takes priority whenever the method is called on a child object, effectively replacing โ or 'overriding' โ the parent's behaviour. This is how a general Vehicle.describe() method can produce a generic description, while Car.describe() produces a more specific one, even though both classes use the same method name.
Overriding does not have to completely discard the parent's logic โ a common and highly recommended pattern is to call super().method_name() inside the override, extending the parent's behaviour rather than replacing it entirely. For example, an overridden describe() method might call super().describe() to get the base description, then append extra Car-specific details onto it.
๐งฉ Method Resolution Order (MRO)
MRO is the precise, deterministic order Python follows when searching through a class hierarchy to find a method or attribute. For simple single inheritance, MRO is intuitive โ search the class itself, then its parent, then its grandparent, and so on. For multiple inheritance, where a class has more than one parent, MRO becomes essential for resolving which parent's version of a shared method name actually gets used. Python calculates MRO using the C3 linearisation algorithm, which guarantees a consistent, predictable order even in complex hierarchies. You can inspect any class's MRO directly using ClassName.__mro__ or ClassName.mro().
๐ isinstance() and issubclass()
isinstance(obj, ClassName) checks whether an object belongs to a given class or any of its subclasses, returning True or False. issubclass(ChildClass, ParentClass) checks whether one class inherits from another, without needing an actual object. Both functions respect the full inheritance chain โ isinstance(my_sports_car, Vehicle) returns True even though my_sports_car is technically a SportsCar, several levels below Vehicle in the hierarchy.
Simple rule to remember: super() lets a child reuse its parent's logic. Overriding lets a child replace or extend a parent's method. MRO decides exactly which version of a method wins when there's more than one candidate in the hierarchy.
Single vs Multiple vs Multilevel Inheritance โ Key Differences
Beginners often mix up these related-but-different inheritance structures. This table lays out exactly how they differ.
Python Inheritance vs Other Languages โ Comparison
Not every object-oriented language treats inheritance the same way. This table compares how Python's approach differs from other popular languages.
Advantages and Disadvantages of Inheritance
Inheritance is one of the most powerful tools in object-oriented design, but overusing it can create its own problems. Understanding both sides helps you decide when inheritance genuinely improves your code.
Inheritance Hierarchy Architecture โ Vehicle Family Example
The diagram below shows a realistic multi-level inheritance hierarchy, illustrating how a general Vehicle class flows down into increasingly specialised classes, and how hierarchical inheritance branches into multiple siblings at the same level.
Your First Python Inheritance Example
Below is a complete, realistic example demonstrating single inheritance, super().__init__(), and method overriding together in a Vehicle-to-Car hierarchy.
class Vehicle:
def __init__(self, brand, speed=0):
self.brand = brand
self.speed = speed
def describe(self):
return f"{self.brand} moving at {self.speed} km/h"
class Car(Vehicle):
def __init__(self, brand, model, speed=0):
super().__init__(brand, speed) # Reuse Vehicle's constructor
self.model = model
def describe(self): # Method overriding
base_description = super().describe() # Extend, not replace
return f"{base_description} โ Model: {self.model}"
car1 = Car("Tesla", "Model 3", 60)
print(car1.describe())
print(isinstance(car1, Vehicle))
print(issubclass(Car, Vehicle))Output
Tesla moving at 60 km/h โ Model: Model 3 True TruePractice This Code โ Live Editor
Line-by-Line Explanation
- โถ
class Car(Vehicle):โ Declares that Car inherits from Vehicle, gaining access to everything Vehicle defines. - โถ
super().__init__(brand, speed)โ Calls Vehicle's constructor first, reusing its logic instead of duplicating self.brand = brand manually. - โถ
def describe(self):(inside Car) โ Overrides Vehicle's describe() method with a more specific version. - โถ
super().describe()โ Inside the override, calls the parent's original describe() to extend it rather than fully replacing it. - โถ
isinstance(car1, Vehicle)โ Returns True because car1, though a Car, is also considered a Vehicle through inheritance. - โถ
issubclass(Car, Vehicle)โ Returns True, confirming Car genuinely inherits from Vehicle at the class level.
Multiple Inheritance and MRO in Action
Multiple inheritance becomes especially useful with mixins โ small classes designed to add one specific piece of behaviour, meant to be combined with other classes rather than used on their own. The example below shows a Car combined with an ElectricMixin.
class Car:
def __init__(self, brand):
self.brand = brand
def info(self):
return f"Car: {self.brand}"
class ElectricMixin:
def info(self):
base = super().info()
return f"{base} (Electric)"
class ElectricCar(ElectricMixin, Car):
pass
car1 = ElectricCar("Tesla")
print(car1.info())
print(ElectricCar.__mro__)Output
Car: Tesla (Electric) (<class '__main__.ElectricCar'>, <class '__main__.ElectricMixin'>, <class '__main__.Car'>, <class 'object'>)Notice the order in class ElectricCar(ElectricMixin, Car): matters enormously. Because ElectricMixin is listed first, Python's MRO places it before Car in the search order, so ElectricMixin.info() runs first โ and its own internal super().info() call then reaches Car.info() next, producing the combined result. Reversing the parent order would change which info() runs first entirely.
Where Inheritance Is Used โ Real-World Applications
Inheritance isn't just a theoretical OOP concept โ it's the structural backbone of many of the most widely used Python frameworks and libraries. Here's where it shows up in practice:
- โถ
๐ Django Model & View Inheritance โ Every Django model inherits from models.Model, gaining database functionality automatically. Class-based views inherit from generic views like ListView or DetailView to gain pre-built behaviour.
- โถ
๐ง PyTorch Neural Network Modules โ Every custom neural network in PyTorch inherits from nn.Module, gaining parameter tracking, GPU support, and serialisation for free, while defining its own forward() method.
- โถ
๐งช Python's Own Exception Hierarchy โ Built-in exceptions like ValueError and TypeError all inherit from the base Exception class, letting a single except Exception: catch any of them, while more specific except blocks catch only particular subtypes.
- โถ
๐ฅ๏ธ GUI Widget Hierarchies โ Tkinter and PyQt build entire widget libraries through inheritance โ a custom button class might inherit from a base Button class to add specialised styling or behaviour.
- โถ
๐งฉ Abstract Base Classes for Plugins โ Plugin systems often define an abstract base class specifying required methods, forcing every plugin (subclass) to implement a consistent interface the main application can rely on.
- โถ
๐ฎ Game Entity Hierarchies โ A game might define a general GameObject base class, with Player, Enemy, and Projectile all inheriting shared position and rendering logic while adding their own specialised behaviour.
- โถ
๐งพ Pydantic & Data Validation Models โ FastAPI and Pydantic rely heavily on inheritance, letting developers build specialised request/response models on top of shared base schemas.
- โถ
โ๏ธ Cloud SDK Client Hierarchies โ SDKs like boto3 often structure different service clients (S3, EC2, Lambda) using shared base classes for authentication and request handling, with service-specific subclasses adding their own methods.
Why Should You Master Inheritance in 2026?
Inheritance shows up everywhere in professional Python development, from the smallest exception hierarchy to the largest web framework. Here's why it deserves serious study:
- โถ
๐ Essential for Reading Framework Code โ Django, FastAPI, PyTorch, and nearly every major framework expect you to inherit from their base classes โ understanding inheritance is non-negotiable for using them effectively.
- โถ
๐งฉ Reduces Duplicate Code โ Well-designed inheritance hierarchies dramatically cut down on repeated logic across related classes, making codebases smaller and easier to maintain.
- โถ
๐ญ Unlocks Polymorphism โ Inheritance is the foundation polymorphism is built on; without understanding inheritance first, polymorphic code patterns are much harder to grasp.
- โถ
๐ผ A Staple Interview Topic โ MRO, super(), method overriding, and the difference between inheritance types are classic Python OOP interview questions at nearly every experience level.
- โถ
๐๏ธ Enables Extensible Design โ Systems designed with inheritance in mind (like abstract base classes for plugins) let new functionality be added by writing new subclasses, without touching existing code.
- โถ
๐ง Deepens Your Understanding of Python's Own Design โ Python's exception system, container types, and even numeric types are all connected through inheritance โ understanding it illuminates how Python itself is built.
Python Versions and Inheritance-Related Features
Inheritance mechanics have been refined steadily across Python's history. Here's a quick reference of version-specific milestones relevant to how inheritance works today:
- โถ
Python 2.2 โ New-Style Classes & C3 Linearisation โ Introduced the modern, predictable MRO algorithm that resolves multiple inheritance consistently, replacing the older, less reliable depth-first search.
- โถ
Python 3.0 โ Zero-Argument super() โ Simplified super(Car, self).method() down to super().method(), removing a significant source of boilerplate and copy-paste errors in inheritance chains.
- โถ
Python 3.4 โ abc Module Improvements โ Strengthened support for Abstract Base Classes, making it easier to define required methods that every subclass must implement.
- โถ
Python 3.6 โ __init_subclass__ Hook โ Added a special method that runs automatically whenever a class is subclassed, useful for registering plugins or validating subclass structure without decorators.
- โถ
Python 3.8 โ typing.Protocol โ Introduced structural subtyping ('if it walks like a duck'), letting code type-check against an interface without requiring formal class inheritance.
- โถ
Python 3.11 โ typing.Self โ Improved type hinting for methods that return an instance of their own class, especially useful in fluent, chainable subclass hierarchies.
- โถ
Python 3.12-3.14 โ Performance Improvements โ Faster attribute and method lookup across deep inheritance chains, reducing the small performance cost that once came with heavily-layered class hierarchies.
Python Inheritance โ Interview Questions (Beginner Level)
These are the most frequently asked interview questions about Python inheritance for freshers and beginner-level positions. Review these carefully before your next Python OOP interview.
Practice Questions โ Test Your Understanding
Test your grasp of Python inheritance with these practice questions. Try answering each one yourself before checking the answer โ active recall builds much stronger, longer-lasting understanding than passive reading.
1. If class Car(Vehicle): does not define its own __init__, what happens when you create a Car object?
Easy2. In class ElectricCar(ElectricMixin, Car):, why does the order of ElectricMixin and Car matter?
Medium3. What does ClassName.__mro__ return, and how would you use it to debug an unexpected method call?
Hard4. Why might calling Vehicle.__init__(self, brand) directly, instead of using super().__init__(brand), cause problems in multiple inheritance?
Hard5. What is the difference between overriding a method completely versus extending it with super()?
Medium6. If Truck and Car both inherit from Vehicle (hierarchical inheritance), does changing Truck affect Car in any way?
Easy7. Why would you use an Abstract Base Class instead of a regular parent class with 'placeholder' methods?
Hard8. What would issubclass(Vehicle, Car) return, given class Car(Vehicle):, and why?
MediumConclusion โ Why Inheritance Matters
Inheritance is what turns a collection of isolated classes into a coherent, extensible family of related types. It is how Django lets you build a fully functional model in a handful of lines, how PyTorch lets you define a neural network by inheriting from nn.Module, and how Python's own exception system lets a single except block gracefully catch an entire family of related errors.
The concepts covered here โ single, multiple, multilevel, and hierarchical inheritance, the super() function, method overriding, and Method Resolution Order (MRO) โ together form the toolkit needed to design class hierarchies that are both powerful and maintainable, rather than tangled and fragile.
The natural next step after mastering inheritance is Polymorphism โ learning how code written against a general parent type can seamlessly work with any of its subclasses, unlocking flexible, extensible designs. From there, encapsulation, abstract base classes, and classic design patterns all build directly on the inheritance foundation covered here.
Used thoughtfully, inheritance turns repetition into reuse and complexity into structure. Practice building your own small class hierarchies, experiment with super() and method overriding, and the concepts will click quickly. ๐งฌ