6.4 Inheritance in Python
Inheritance is one of the key principles of Object-Oriented Programming (OOP) that allows a new class (called a child class or subclass) to inherit attributes and methods from an existing class (called a parent class or superclass). Inheritance enables code reuse, allows for hierarchical class relationships, and supports polymorphism.
In this section, we’ll explore how to implement inheritance, extend or override methods, and understand the concept of multi-level and multiple inheritance.
6.4.1 What is Inheritance?
Inheritance is a mechanism that allows a class (child class) to inherit attributes and methods from another class (parent class). The child class can use the inherited features as-is, modify them, or add new attributes and methods of its own.
Benefits of Inheritance:
- Code Reusability: You can reuse existing code in new contexts without rewriting it.
- Extensibility: You can extend the functionality of an existing class by adding new methods and attributes.
- Organized Hierarchy: Classes can be organized in a logical hierarchy, making code more modular and easier to maintain.
6.4.2 Defining a Parent Class (Superclass)
A parent class is the class that passes down its properties and behaviors to the child class. You define a parent class like any other class.
Example: Defining a Vehicle
Class
class Vehicle:
def __init__(self, brand, model):
self.brand = brand
self.model = model
def start(self):
print(f"The {self.brand} {self.model} is starting.")
def stop(self):
print(f"The {self.brand} {self.model} is stopping.")
Here, the Vehicle
class defines two instance attributes (brand
and model
) and two methods (start()
and stop()
). This class can now be inherited by other classes to reuse these attributes and methods.
6.4.3 Creating a Child Class (Subclass)
A child class (also called a subclass) inherits the attributes and methods from the parent class. To define a child class, you specify the parent class in parentheses when defining the subclass.
Syntax:
class ChildClass(ParentClass):
# Additional attributes and methods
Example: Creating a Car
Subclass that Inherits from Vehicle
class Car(Vehicle):
def __init__(self, brand, model, year):
# Call the parent class's constructor using super()
super().__init__(brand, model)
self.year = year # New attribute specific to Car
def display_info(self):
return f"{self.year} {self.brand} {self.model}"
In this example:
- The
Car
class inherits from theVehicle
class. - The
Car
class uses thesuper()
function to call the__init__()
method of the parent class (Vehicle
) to initialize thebrand
andmodel
attributes. - The
Car
class also adds a new attributeyear
and defines an additional methoddisplay_info()
.
Creating an Object from the Child Class:
my_car = Car("Toyota", "Corolla", 2020)
my_car.start() # Output: The Toyota Corolla is starting.
my_car.stop() # Output: The Toyota Corolla is stopping.
print(my_car.display_info()) # Output: 2020 Toyota Corolla
In this example:
- The
Car
object has access to both the inherited methods (start()
andstop()
) from theVehicle
class and its own methoddisplay_info()
.
6.4.4 The super()
Function
The super()
function is used to call methods from the parent class. It is commonly used in the child class's __init__()
method to ensure that the parent class's constructor is called to properly initialize inherited attributes.
Example:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print(f"{self.name} says woof!")
class GuardDog(Dog):
def __init__(self, name, breed, training_level):
# Call the parent class's constructor
super().__init__(name, breed)
self.training_level = training_level
def display_training(self):
print(f"{self.name} is trained to level {self.training_level}.")
In this example:
- The
GuardDog
class usessuper().__init__(name, breed)
to call the parent class's constructor, ensuring that thename
andbreed
attributes are properly initialized.
Using the Subclass:
rex = GuardDog("Rex", "German Shepherd", 5)
rex.bark() # Output: Rex says woof!
rex.display_training() # Output: Rex is trained to level 5.
Here, the GuardDog
object inherits the bark()
method from the Dog
class and introduces a new method display_training()
.
6.4.5 Overriding Methods
A child class can override methods from the parent class by defining a method with the same name in the child class. This allows the child class to provide its own implementation while retaining the ability to call the parent class's version using super()
.
Example: Overriding the start()
Method
class ElectricCar(Car):
def start(self):
print(f"The {self.brand} {self.model} (Electric) is starting silently.")
In this case:
- The
ElectricCar
class overrides thestart()
method from theCar
class, providing a different implementation.
Using the Overridden Method:
my_electric_car = ElectricCar("Tesla", "Model 3", 2021)
my_electric_car.start() # Output: The Tesla Model 3 (Electric) is starting silently.
The ElectricCar
class overrides the start()
method to provide a custom behavior, while still inheriting other methods from the parent class.
6.4.6 Extending Methods
You can extend a method from the parent class by calling the parent class's version of the method using super()
, and then adding additional functionality in the child class.
Example:
class SmartCar(Car):
def start(self):
# Call the parent class's start method
super().start()
print(f"The {self.brand} {self.model} is now in smart mode.")
Here, the start()
method in SmartCar
extends the behavior of the start()
method from the parent class by calling super().start()
and then adding additional functionality.
Using the Extended Method:
my_smart_car = SmartCar("Tesla", "Model S", 2022)
my_smart_car.start()
# Output:
# The Tesla Model S is starting.
# The Tesla Model S is now in smart mode.
6.4.7 Multi-Level Inheritance
Multi-level inheritance is when a class inherits from another class, which itself inherits from another class. This creates a hierarchy where each class can extend or modify the behavior of its parent.
Example:
class Animal:
def speak(self):
print("The animal makes a sound.")
class Dog(Animal):
def speak(self):
print("The dog barks.")
class GuardDog(Dog):
def speak(self):
print("The guard dog growls.")
# Creating an object of GuardDog
guard_dog = GuardDog()
guard_dog.speak() # Output: The guard dog growls.
In this example:
GuardDog
inherits fromDog
, which inherits fromAnimal
.- The
speak()
method is overridden at each level, with the most specific version (inGuardDog
) being called.
6.4.8 Multiple Inheritance
Multiple inheritance is when a class inherits from more than one parent class. This allows a child class to inherit methods and attributes from multiple sources.
Syntax:
class ChildClass(ParentClass1, ParentClass2):
# Class definition
Example:
class Flyer:
def fly(self):
print("Flying high!")
class Swimmer:
def swim(self):
print("Swimming in water!")
class Duck(Flyer, Swimmer):
pass
# Creating a Duck object
donald = Duck()
donald.fly() # Output: Flying high!
donald.swim() # Output: Swimming in water!
In this example:
- The
Duck
class inherits from bothFlyer
andSwimmer
, allowing it to use methods from both parent classes.
6.4.9 The isinstance()
and issubclass()
Functions
- **
isinstance()
: This function checks if an object is an instance of a class or a subclass of that class.
Example:
print(isinstance(my_car, Car)) # Output: True
print(isinstance(my_car, Vehicle)) # Output: True
issubclass()
**: This function checks if a class is a subclass of another class.
Example:
print(issubclass(Car, Vehicle)) # Output: True
print(issubclass(ElectricCar, Car)) # Output: True
6.4.10 Summary
- Inheritance allows a class to inherit attributes and methods from a parent class, enabling code reuse and extensibility.
- The
super()
function is used to call methods from the parent class, commonly in constructors or when extending methods. - You can override methods in the child class to provide custom behavior and extend methods to add functionality while preserving the parent class’s behavior.
- Multi-level inheritance creates a hierarchy of inheritance, while multiple inheritance allows a class to inherit from more than one parent class.
- Use the
isinstance()
andissubclass()
functions to check relationships between objects and classes.
Understanding inheritance is key to building efficient, modular, and scalable applications in Python. It allows you to create hierarchies of classes, extend functionality, and manage code in a more organized way.