Inheritance: Reuse and Extend Class Behavior

Introduction

In this chapter, you will learn inheritance in Python, a key concept in object-oriented programming. Inheritance lets one class reuse and extend another class's attributes and methods. This helps you reduce duplicate code and build cleaner class hierarchies.

Prerequisites

  • Python 3.10+ installed
  • Basic understanding of classes, objects, methods, and constructors
  • Ability to run .py files in terminal or IDE

What Is Inheritance

Inheritance means a child class can inherit features from a parent class.

Think of it like:

  • Parent class: general template
  • Child class: specialized version with extra behavior

Benefits:

  • code reuse
  • clearer structure
  • easier maintenance

1) Basic Inheritance Syntax

Use parentheses after child class name to specify parent class.

python
# Parent class
class Animal:
    def eat(self):
        print("This animal can eat.")
 
 
# Child class inherits from Animal
class Dog(Animal):
    def bark(self):
        print("Woof!")
 
 
# Create child object
dog = Dog()
dog.eat()   # inherited method
dog.bark()  # child method

Dog can use both its own methods and inherited methods.

2) Inheriting Constructor with super()

Use super() to call parent constructor.

python
# Parent class
class Person:
    def __init__(self, name):
        self.name = name
 
 
# Child class
class Student(Person):
    def __init__(self, name, grade):
        # Call parent constructor
        super().__init__(name)
        self.grade = grade
 
 
# Create object
stu = Student("Emma", "Grade 5")
print(stu.name)
print(stu.grade)

super() avoids repeating parent initialization logic.

3) Method Overriding

Child classes can redefine parent methods.

python
# Parent class
class Animal:
    def speak(self):
        print("Animal sound")
 
 
# Child class overrides method
class Cat(Animal):
    def speak(self):
        print("Meow")
 
 
# Test overriding
cat = Cat()
cat.speak()  # Meow

Tip

Best Practice

When overriding, keep method names meaningful and behavior consistent with parent intent.

4) Call Parent Method from Child

Sometimes you want to extend, not fully replace, parent behavior.

python
# Parent class
class Animal:
    def speak(self):
        print("Animal sound")
 
 
# Child class extends parent behavior
class Bird(Animal):
    def speak(self):
        # Call parent method first
        super().speak()
        print("Tweet")
 
 
bird = Bird()
bird.speak()

Output includes both parent and child messages.

5) Real Mini Example: School Roles

This example models roles using inheritance.

python
# Parent class
class SchoolMember:
    def __init__(self, name):
        self.name = name
 
    def introduce(self):
        print(f"My name is {self.name}.")
 
 
# Student class
class Student(SchoolMember):
    def __init__(self, name, score):
        super().__init__(name)
        self.score = score
 
    def introduce(self):
        print(f"I am student {self.name}, score: {self.score}.")
 
 
# Teacher class
class Teacher(SchoolMember):
    def __init__(self, name, subject):
        super().__init__(name)
        self.subject = subject
 
    def introduce(self):
        print(f"I am teacher {self.name}, subject: {self.subject}.")
 
 
# Create objects
member_list = [
    Student("Liam", 92),
    Teacher("Ms. Brown", "Chinese")
]
 
# Polymorphic call
for member in member_list:
    member.introduce()

This is a practical way to model shared and specialized behavior.

6) Multiple Inheritance (Beginner Awareness)

Python supports multiple inheritance, but beginners should use it carefully.

python
# Parent class A
class Runner:
    def run(self):
        print("Running")
 
 
# Parent class B
class Swimmer:
    def swim(self):
        print("Swimming")
 
 
# Child class inherits both
class Athlete(Runner, Swimmer):
    pass
 
 
athlete = Athlete()
athlete.run()
athlete.swim()

Warning

Multiple inheritance can become complex in large projects.
Prefer single inheritance unless there is a clear design reason.

Common Beginner Mistakes

Mistake 1: Forgetting super().__init__()

If child class defines its own constructor and skips parent constructor call, parent attributes may be missing.

Mistake 2: Overriding Without Understanding Parent Contract

Changing method behavior too much can break expected usage patterns.

Mistake 3: Creating Deep Inheritance Chains Too Early

Very deep hierarchies are hard to understand and maintain for beginners.

Surprise Practice Challenge

Build a "Vehicle Family" mini design:

  1. Parent class Vehicle with brand and method start()
  2. Child class Car with extra attribute doors
  3. Child class Bike with extra attribute has_pedals
  4. Override start() in at least one child class
  5. Create objects and print behavior

If you finish this, you already understand practical inheritance design basics.

FAQ

Why use inheritance instead of copying code?

Inheritance centralizes shared logic and reduces duplication.

What is the difference between inheritance and composition?

Inheritance models an "is-a" relationship; composition models a "has-a" relationship.

Should I always use inheritance in OOP?

No. Use inheritance when there is a clear shared abstraction; otherwise composition may be simpler.

Is method overriding required in child classes?

No. Child classes can use parent methods directly unless customization is needed.