Python Inheritance: When to Use It and Skip It

Boot.dev Blog » Python » Python Inheritance: When to Use It and Skip It
Lane Wagner
Lane Wagner Boot.dev co-founder and backend engineer

Last published March 20, 2026

Table of Contents

Inheritance is one of those OOP tools that feels magical on day one and dangerous on day thirty. Used well, it removes duplication and keeps models clean. Used badly, it creates class trees no one wants to touch.

All the content from our Boot.dev courses are available for free here on the blog. This one is the “Inheritance” chapter of Learn Object Oriented Programming in Python. If you want to try the far more immersive version of the course, do check it out!

What Is Inheritance in Python?

In inheritance, a child class gets behavior from a parent class. In Python, you declare that relationship with parentheses after the child class name.

class Aircraft:
    def __init__(self, height, speed):
        self.height = height
        self.speed = speed

    def fly_up(self):
        self.height += self.speed


class Helicopter(Aircraft):
    def __init__(self, height, speed):
        super().__init__(height, speed)
        self.direction = 0

    def rotate(self):
        self.direction += 90


news_copter = Helicopter(100, 20)
news_copter.fly_up()
news_copter.rotate()
print(news_copter.height, news_copter.direction)  # 120 90

Helicopter reuses Aircraft.fly_up() and adds its own rotate() behavior. That’s the core value: reuse plus specialization.

If this still feels fuzzy, read Python classes and objects first, then come back.

How Does super() Work in Child Classes?

super() gives your child class access to methods on its parent. Most of the time, you use it in __init__ so parent setup always runs.

class Hero:
    def __init__(self, name, health):
        self.name = name
        self.health = health


class Wizard(Hero):
    def __init__(self, name, health, mana):
        super().__init__(name, health)
        self.mana = mana


gandalf = Wizard("Gandalf", 120, 250)
print(gandalf.name, gandalf.health, gandalf.mana)  # Gandalf 120 250

Without super(), you’ll duplicate parent setup in every child. That’s where bugs creep in fast.

When Should a Class Inherit?

Use this rule: class A should inherit from class B only if A is always a B.

  • Cat is always an Animal.
  • Truck is always a Vehicle.
  • Square is always a Rectangle in many teaching models.

Bad inheritance usually starts when you force a relationship to share a little code. If two classes share one helper method but don’t share identity, inheritance is the wrong tool.

When that happens, use regular functions or composition instead. This is the same design pressure discussed in Python clean code and DRY tradeoffs.

What Makes a Good Inheritance Hierarchy?

A good child class is a strict subset of its parent. It keeps parent promises and adds narrower behavior.

class Archer(Hero):
    def __init__(self, name, health, arrows):
        super().__init__(name, health)
        self.__arrows = arrows

    def shoot(self, target):
        if self.__arrows <= 0:
            raise Exception("not enough arrows")
        self.__arrows -= 1
        target.health -= 10


class Wizard(Hero):
    def __init__(self, name, health, mana):
        super().__init__(name, health)
        self.__mana = mana

Both Archer and Wizard are heroes. That’s a clean parent/child relationship.

This “group data and behavior” mindset will feel familiar if you’ve already worked through encapsulation and abstraction.

Why Are Wide Trees Better Than Deep Trees?

Most inheritance in (good) production code is wide, not deep.

Deep chains mean a child must satisfy every parent assumption all the way up the tree. That gets brittle. Wide trees are usually easier:

  • One stable base class
  • Many sibling classes
  • Small, focused overrides

If you find yourself building Camera -> Device -> Electronic -> InventoryItem -> GameEntity -> Object, stop and reevaluate. You probably want composition.

How Do Sibling Classes Share One Parent?

Siblings inherit from the same parent and reuse shared behavior while implementing different actions.

class Hero:
    def __init__(self, name, health):
        self.name = name
        self.health = health


class Archer(Hero):
    def shoot(self, target):
        target.health -= 10


class Wizard(Hero):
    def cast(self, target):
        target.health -= 25


legolas = Archer("Legolas", 100)
saruman = Wizard("Saruman", 100)
legolas.shoot(saruman)
print(saruman.health)  # 90
saruman.cast(legolas)
print(legolas.health)  # 75

That gives you a clean family of related types, which also sets up chapter 6’s polymorphism nicely.

When Should You Prefer Composition Over Inheritance?

If a class only needs one small behavior from another type, composition is usually cleaner than inheritance.

class DamageCalculator:
    def weapon_hit(self, attack, defense):
        return max(0, attack - defense)


class Warrior:
    def __init__(self, name, attack, defense):
        self.name = name
        self.attack = attack
        self.defense = defense
        self.damage_calculator = DamageCalculator()

    def hit(self, target):
        return self.damage_calculator.weapon_hit(self.attack, target.defense)

Warrior doesn’t need to be a DamageCalculator. It only needs to use one. That’s exactly where composition shines.

What Should You Learn After Python Inheritance?

After inheritance, the next big step is polymorphism. That’s where shared method names across related classes start paying off in a huge way.

Keep going in Learn Object Oriented Programming in Python. If you want to balance OOP with another mental model, pair it with Learn Functional Programming in Python. For long-term backend growth, follow the Back-end Developer Path in Python and Go.

Frequently Asked Questions

What is inheritance in Python?

Inheritance lets a child class reuse data and methods from a parent class, then add or override behavior.


When should I use inheritance?

Use inheritance when the child is always a strict type of the parent and needs most of the parent behavior.


What does super() do in Python?

super() gives access to parent-class methods, most commonly the parent constructor, so child setup can reuse parent logic.


Is deep inheritance a good idea?

Usually no. Most real systems are easier to maintain with wide, shallow hierarchies instead of deep chains.


Should I use inheritance or composition?

If you only need to share a small piece of behavior, composition is often cleaner. Use inheritance when the is-a relationship is always true.

Related Articles