← Back to Articles
Tutorial

Python Inheritance – Object-Oriented Programming Guide

Master Python inheritance with super(), method overriding, abstract classes, multiple inheritance, and Method Resolution Order (MRO).

📌 Python inheritance, OOP inheritance, super() Python, multiple inheritance, abstract classes, MRO Python

Inheritance is a fundamental OOP concept allowing creation of new classes based on existing ones. Child classes receive parent class attributes and methods while enabling extension and modification—representing an 'is-a' relationship where a dog IS an animal, a car IS a vehicle.

Inheritance delivers four key benefits: code reuse eliminates duplication, logical hierarchies reflect natural object relationships, extensibility facilitates new functionality addition, and polymorphism enables uniform object usage across different classes.

The super() function is essential for accessing parent class methods from child classes. It enables functionality extension rather than complete replacement, allowing child classes to build upon parent behavior while adding their own customizations.

Abstract classes serve as templates requiring subclass implementation. Using ABC (Abstract Base Class) with @abstractmethod decorator ensures child classes implement specified methods—perfect for defining interfaces that guarantee consistent behavior across subclasses.

Multiple inheritance allows classes to inherit from multiple parents, accessing methods from all sources. Python's Method Resolution Order (MRO) determines which parent method executes first when there are conflicts—displayed via __mro__ attribute.

Code Examples

Basic Inheritance

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "Some sound"

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

dog = Dog("Buddy")
print(dog.name)     # "Buddy" (inherited)
print(dog.speak())  # "Woof!" (overridden)

Using super() to Extend Parent Behavior

class Vehicle:
    def __init__(self, brand):
        self.brand = brand
        self.speed = 0

    def accelerate(self, amount):
        self.speed += amount

class Car(Vehicle):
    def __init__(self, brand, fuel_type):
        # Call parent __init__
        super().__init__(brand)
        self.fuel_type = fuel_type

    def accelerate(self, amount):
        # Extend parent behavior
        super().accelerate(amount)
        print(f"Speed: {self.speed} km/h")

my_car = Car("Toyota", "electric")
my_car.accelerate(50)
# Output: Speed: 50 km/h

Multi-level Inheritance

class LivingThing:
    def breathe(self):
        return "Breathing..."

class Animal(LivingThing):
    def move(self):
        return "Moving..."

class Mammal(Animal):
    def feed_young(self):
        return "Feeding young..."

class Dog(Mammal):
    def bark(self):
        return "Woof!"

dog = Dog()
print(dog.breathe())       # From LivingThing
print(dog.move())          # From Animal
print(dog.feed_young())    # From Mammal
print(dog.bark())          # From Dog

Abstract Base Classes

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        """Calculate area of the shape"""
        pass

    @abstractmethod
    def perimeter(self):
        """Calculate perimeter of the shape"""
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

    def perimeter(self):
        return 2 * 3.14 * self.radius

# rect = Shape()  # Error - can't instantiate abstract class
rect = Rectangle(5, 3)
print(rect.area())  # 15

Multiple Inheritance

class Flyable:
    def fly(self):
        return "Flying high!"

class Swimmable:
    def swim(self):
        return "Swimming gracefully!"

class Duck(Flyable, Swimmable):
    def quack(self):
        return "Quack!"

donald = Duck()
print(donald.fly())    # "Flying high!"
print(donald.swim())   # "Swimming gracefully!"
print(donald.quack())  # "Quack!"

Method Resolution Order (MRO)

class A:
    def method(self):
        return "A"

class B(A):
    def method(self):
        return "B"

class C(A):
    def method(self):
        return "C"

class D(B, C):
    pass

d = D()
print(d.method())  # "B" (B comes before C in inheritance)

# Check MRO
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>,
#  <class '__main__.C'>, <class '__main__.A'>,
#  <class 'object'>)

Checking Class Relationships

class Animal:
    pass

class Dog(Animal):
    pass

dog = Dog()

# isinstance checks object instances
print(isinstance(dog, Dog))      # True
print(isinstance(dog, Animal))   # True
print(isinstance(dog, object))   # True

# issubclass checks class relationships
print(issubclass(Dog, Animal))   # True
print(issubclass(Animal, Dog))   # False
print(issubclass(Dog, object))   # True

More Python Tutorials