Python Inheritance

Learn how to create relationships between classes and reuse code effectively

🧬 Understanding Inheritance

Inheritance is a fundamental concept in Object-Oriented Programming (OOP) that allows a class (child or derived class) to inherit attributes and methods from another class (parent or base class). This promotes code reusability and establishes a natural "is-a" relationship between classes.


# Basic inheritance example
class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"
                                    
5
Types
Reusable
Code
Hierarchical
Structure

What is Inheritance?

When a class inherits from another, it gains all the public and protected members (attributes and methods) of the parent class. This means you don't have to rewrite the same code multiple times. Instead, you can define common functionalities in a base class and then extend them in derived classes.

Parent Class (Person)

  • firstname
  • lastname
  • printname()
⬇️

Child Class (Student)

  • firstname (inherited)
  • lastname (inherited)
  • printname() (inherited)
  • graduationyear (new)
  • welcome() (new)
basic_inheritance.py
class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname

    def printname(self):
        print(self.firstname, self.lastname)

# Use the Person class
x = Person("John", "Doe")
x.printname()

class Student(Person):  # Student inherits from Person
    pass  # Use 'pass' when you don't want to add any other properties or methods

# Use the Student class
y = Student("Mike", "Olsen")
y.printname()  # This works because Student inherited printname from Person

The __init__() Function in Child Classes

When you add the __init__() function to a child class, the child class will no longer inherit the parent's __init__() function. The child's __init__() will override the parent's.

💡 Important Note:

To keep the inheritance of the parent's __init__() function, you need to explicitly call it within the child's __init__() function.

init_inheritance.py
class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname

    def printname(self):
        print(self.firstname, self.lastname)

class Student(Person):
    def __init__(self, fname, lname, year):
        # Call the parent's __init__ method
        Person.__init__(self, fname, lname) 
        self.graduationyear = year

    def welcome(self):
        print("Welcome", self.firstname, self.lastname, "to the class of", self.graduationyear)

student1 = Student("Emily", "Clark", 2025)
student1.printname()
student1.welcome()

The super() Function

Python also has a super() function that will make the child class inherit all the methods and properties from its parent. By using the super() function, you don't have to use the name of the parent element, which makes the code more maintainable and flexible.

✨ Benefits of using super():

🔧

Maintainable

No need to specify parent class name

🔄

Flexible

Easy to change parent class

📈

Scalable

Works with multiple inheritance

super_example.py
class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname

    def printname(self):
        print(self.firstname, self.lastname)

class Student(Person):
    def __init__(self, fname, lname, year):
        super().__init__(fname, lname)  # Calls Person's __init__
        self.graduationyear = year

    def welcome(self):
        print("Welcome", self.firstname, self.lastname, "to the class of", self.graduationyear)

student2 = Student("David", "Lee", 2024)
student2.printname()
student2.welcome()

Adding Properties and Methods to Child Class

You can add new properties and methods to the child class that are specific to it, while still retaining the inherited ones.

vehicle_inheritance.py
class Vehicle:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def display_info(self):
        print(f"Brand: {self.brand}, Model: {self.model}")

class Car(Vehicle):
    def __init__(self, brand, model, year):
        super().__init__(brand, model)
        self.year = year  # New property specific to Car

    def honk(self):  # New method specific to Car
        print("Beep, beep!")

    def display_info(self):  # Overriding parent method
        super().display_info()  # Call parent's method
        print(f"Year: {self.year}")

my_car = Car("Toyota", "Camry", 2020)
my_car.display_info()
my_car.honk()

Types of Inheritance

1️⃣

Single Inheritance

A class inherits from one base class (most common)

class Child(Parent):
2️⃣

Multiple Inheritance

A class inherits from multiple base classes

class Child(Parent1, Parent2):
3️⃣

Multi-level Inheritance

A class inherits from a base class, then another class inherits from this derived class

A → B → C
4️⃣

Hierarchical Inheritance

Multiple derived classes inherit from a single base class

A → B, A → C, A → D
5️⃣

Hybrid Inheritance

A combination of two or more types of inheritance

Mixed patterns

Real-World Example: Employee Management System

employee_system.py
class Employee:
    """Base class for all employees"""
    def __init__(self, name, employee_id, salary):
        self.name = name
        self.employee_id = employee_id
        self.salary = salary
    
    def display_info(self):
        print(f"Employee: {self.name} (ID: {self.employee_id})")
        print(f"Salary: ${self.salary:,.2f}")
    
    def get_annual_bonus(self):
        return self.salary * 0.05  # 5% bonus

class Developer(Employee):
    """Developer class inheriting from Employee"""
    def __init__(self, name, employee_id, salary, programming_languages):
        super().__init__(name, employee_id, salary)
        self.programming_languages = programming_languages
    
    def display_info(self):
        super().display_info()
        print(f"Role: Software Developer")
        print(f"Languages: {', '.join(self.programming_languages)}")
    
    def get_annual_bonus(self):
        # Developers get 10% bonus
        return self.salary * 0.10

class Manager(Employee):
    """Manager class inheriting from Employee"""
    def __init__(self, name, employee_id, salary, team_size):
        super().__init__(name, employee_id, salary)
        self.team_size = team_size
    
    def display_info(self):
        super().display_info()
        print(f"Role: Manager")
        print(f"Team Size: {self.team_size} people")
    
    def get_annual_bonus(self):
        # Managers get 15% bonus
        return self.salary * 0.15

# Create instances
dev = Developer("Alice Johnson", "DEV001", 75000, ["Python", "JavaScript", "React"])
manager = Manager("Bob Smith", "MGR001", 95000, 8)

print("=== DEVELOPER INFO ===")
dev.display_info()
print(f"Annual Bonus: ${dev.get_annual_bonus():,.2f}")

print("\n=== MANAGER INFO ===")
manager.display_info()
print(f"Annual Bonus: ${manager.get_annual_bonus():,.2f}")

🧠 Test Your Knowledge

Which keyword is used to define a class that inherits from another class in Python?

What is the primary purpose of the super() function in inheritance?