Skip to content

Inheritance in Python: A Comprehensive Guide to Creating Child Classes That Inherit Attributes and Methods

Updated: at 02:01 AM

Inheritance is a fundamental concept in object-oriented programming that allows new child classes to be derived from existing parent classes. The child class inherits the attributes and methods of the parent, allowing code reuse and the creation of specialized classes.

This comprehensive Python programming guide will explain inheritance in detail, including key concepts like polymorphism and method overriding. Through clear explanations and annotated code examples, you will learn how to utilize inheritance in Python to design flexible, modular programs.

We will cover:

By the end, you will have a strong grasp of leveraging inheritance to write concise, maintainable, and extensible Python code. The concepts can be applied to various domains like game development, web programming, machine learning, and more.

Inheritance Basics

Inheritance allows a new class to be defined that reuses, extends, and modifies the behavior of an existing class. The existing class is called the parent class or base class, and the new class is the child class or derived class.

class ParentClass:
    # Parent class definition

class ChildClass(ParentClass):
    # Child class inherits from ParentClass

The child class inherits the attributes and methods of the parent, so we can leverage all existing functionality without rewriting it. At the same time, we can override methods to provide specialized implementations in the child.

Key benefits of using inheritance in Python:

Creating Parent and Child Classes

To demonstrate inheritance, let’s start by defining a simple Vehicle parent class with some attributes and methods:

class Vehicle:

    def __init__(self, make, color, fuel_type):
        self.make = make
        self.color = color
        self.fuel_type = fuel_type

    def drive(self):
        print("Driving the vehicle!")

    def add_fuel(self, amount):
        print(f"Added {amount} gallons of {self.fuel_type} fuel.")

This parent class initializes each vehicle with make, color and fuel_type attributes in the constructor. It also contains drive() and add_fuel() methods that all vehicles need.

We can now create a child class Car that inherits from Vehicle:

class Car(Vehicle):
    # Car class inherits from Vehicle

The Car class will have access to all attributes and methods of Vehicle. We can demonstrate this by instantiating Car and calling the inherited drive() method:

my_car = Car("Tesla", "red", "electric")
my_car.drive() # Inherited method

This outputs:

Driving the vehicle!

So the Car instance can utilize the drive() logic we defined in the parent Vehicle class.

Inheriting Attributes and Methods

By default, all attributes and methods from the parent are inherited by child classes.

For example, we can access my_car’s make, color and fuel_type attributes inherited from Vehicle:

print(my_car.make) # Tesla
print(my_car.color) # red
print(my_car.fuel_type) # electric

The child Car class also inherits the add_fuel() method:

my_car.add_fuel(25) # Method inherited from Vehicle

Outputs:

Added 25 gallons of electric fuel.

This demonstrates how inheriting from Vehicle gives Car access to pre-built attributes and methods, avoiding code duplication.

We can also define additional custom attributes and methods in the child class:

class Car(Vehicle):

    num_wheels = 4

    def lock_doors(self):
        print("Doors locked!")

These are specific to Car instances and not inherited from Vehicle.

The super() Function

The super() function provides access to inherited methods that have been overridden in the child class. This allows you to leverage the inherited implementation when overriding a method.

For example, let’s override drive() in Car:

class Car(Vehicle):

    def drive(self):
        print("Driving the car!")
        super().drive() # Call parent drive() method

Now when we call drive(), it will print out the Car custom string but still retain the core Vehicle drive() behavior:

my_car.drive()

Output:

Driving the car!
Driving the vehicle!

So super() allows the inherited parent behavior to be reused even when overriding a method.

Method Overriding

Method overriding is the concept of redefining a method in the child class that already exists in the parent. This allows child classes to provide specialized implementations tailored to their needs.

Let’s modify the add_fuel() method in Car to be specific to electric vehicles:

class Car(Vehicle):

    def add_fuel(self, kwh):
        print(f"Charging battery with {kwh} kWh of electricity.")

When we call add_fuel(), it will now use the Car version instead of the parent Vehicle one:

my_car.add_fuel(85)

Outputs:

Charging battery with 85 kWh of electricity.

Overriding methods like this allows child classes to specialize the inherited behavior.

Polymorphism and Abstract Base Classes

Polymorphism refers to a child class object being able to be treated like a parent class object, because they share attributes and methods.

For example, we can have a list containing different vehicle objects, and call drive() polymorphically on each:

cars = [Car("Tesla", ...), Car("Toyota", ...)]

for vehicle in cars:
    vehicle.drive()

This demonstrates polymorphic behavior - treating each child instance as its parent type.

To define common interfaces for a group of related classes, we can use abstract base classes (ABCs). An abstract method can be defined without implementation that child classes must override:

from abc import ABC, abstractmethod

class Vehicle(ABC):

    @abstractmethod
    def drive(self):
        pass

class Car(Vehicle):

    def drive(self):
        print("Driving the car!")

Any child of Vehicle must implement drive() or an error occurs. This enforces a common interface.

Multiple Inheritance

Python supports multiple inheritance, where a class can inherit from multiple parent classes.

For example:

class GasVehicle(Vehicle):
    # Fuel methods for gas vehicles

class ElectricVehicle(Vehicle):
    # Charging methods for electric vehicles

class HybridCar(GasVehicle, ElectricVehicle):
    # Hybrid cars inherit from both parent classes

The child HybridCar class can access methods and attributes from both GasVehicle and ElectricVehicle.

The order of inheritance determines the method resolution order - the order methods are looked up in when called. Child classes precede parents, and the leftmost parent is checked first.

Common Applications of Inheritance

Some common use cases for leveraging inheritance in Python include:

Inheritance enables the “is-a” relationship between classes to reuse common logic in a hierarchy while allowing specialization as needed.

Conclusion

This guide provided a comprehensive overview of inheritance in Python. We covered key concepts like:

Inheritance is a powerful tool for extending class functionality in Python. Using it appropriately leads to code reuse, well-organized hierarchies, and maintainable programs.

The concepts can be applied across domains like game programming. web development, scientific computing and more. Mastering inheritance is an important milestone for any intermediate Python programmer.

There are many additional techniques and patterns related to inheritance that can be explored further, but this guide covers the core foundations you need to start utilizing inheritance effectively in your own Python projects.