
Inheritance is one of the fundamental concepts of object-oriented programming (OOP) that allows a class to inherit attributes and methods from another class. In Python, inheritance enables code reusability and the creation of hierarchical relationships between classes. This article will explain Python inheritance with practical examples to help you understand and implement this powerful feature.
Understanding Inheritance in Python
Inheritance creates a parent-child relationship between classes where:
- The parent class (also called base class or superclass) is the class being inherited from
- The child class (also called derived class or subclass) is the class that inherits from another class
The child class automatically gets access to all the methods and attributes of the parent class while being able to define its own unique features.
Basic Syntax
class ParentClass:
# Parent class attributes and methods
pass
class ChildClass(ParentClass):
# Child class attributes and methods
pass
Types of Inheritance in Python
Python supports several types of inheritance:
- Single Inheritance: A child class inherits from a single parent class
- Multiple Inheritance: A child class inherits from multiple parent classes
- Multilevel Inheritance: A child class inherits from a parent class which itself inherits from another class
- Hierarchical Inheritance: Multiple child classes inherit from a single parent class
- Hybrid Inheritance: A combination of two or more inheritance types
Practical Examples of Python Inheritance
Example 1: Single Inheritance
# Parent class
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some sound"
# Child class inheriting from Animal
class Dog(Animal):
def speak(self):
return "Woof!"
# Create instances
animal = Animal("Generic Animal")
dog = Dog("Buddy")
print(animal.name, "says", animal.speak()) # Generic Animal says Some sound
print(dog.name, "says", dog.speak()) # Buddy says Woof!
In this example:
Dog
inherits fromAnimal
Dog
gets access to the__init__
method andname
attribute fromAnimal
Dog
overrides thespeak
method with its own implementation
Example 2: Multiple Inheritance
class Flyable:
def fly(self):
return "I can fly!"
class Swimmable:
def swim(self):
return "I can swim!"
class Duck(Flyable, Swimmable):
def speak(self):
return "Quack!"
duck = Duck()
print(duck.fly()) # I can fly!
print(duck.swim()) # I can swim!
print(duck.speak()) # Quack!
Here, the Duck
class inherits from both Flyable
and Swimmable
, gaining methods from both parent classes.
Example 3: Multilevel Inheritance
class Vehicle:
def __init__(self, make, model):
self.make = make
self.model = model
def info(self):
return f"{self.make} {self.model}"
class Car(Vehicle):
def __init__(self, make, model, doors):
super().__init__(make, model)
self.doors = doors
def info(self):
return f"{super().info()} with {self.doors} doors"
class ElectricCar(Car):
def __init__(self, make, model, doors, battery_size):
super().__init__(make, model, doors)
self.battery_size = battery_size
def info(self):
return f"{super().info()} and {self.battery_size}kWh battery"
tesla = ElectricCar("Tesla", "Model S", 4, 100)
print(tesla.info()) # Tesla Model S with 4 doors and 100kWh battery
This demonstrates a chain of inheritance: ElectricCar
→ Car
→ Vehicle
.
The super()
Function
The super()
function allows you to call methods from the parent class. This is particularly useful when:
- You want to extend the functionality of a parent method rather than completely override it
- You need to access parent class methods in multiple inheritance scenarios
class Parent:
def __init__(self, name):
self.name = name
class Child(Parent):
def __init__(self, name, age):
super().__init__(name) # Calls Parent.__init__()
self.age = age
child = Child("Alice", 10)
print(child.name) # Alice
print(child.age) # 10
Method Resolution Order (MRO)
In multiple inheritance, Python follows a specific order to search for methods and attributes. This is called Method Resolution Order (MRO). You can view the MRO of a class using the __mro__
attribute or the mro()
method.
print(Duck.__mro__)
# Output: (<class '__main__.Duck'>, <class '__main__.Flyable'>,
# <class '__main__.Swimmable'>, <class 'object'>)
When to Use Inheritance
Inheritance is appropriate when:
- There’s a clear “is-a” relationship between classes
- You need to share common behavior among related classes
- You want to extend or modify existing functionality
However, overusing inheritance can lead to complex, hard-to-maintain code. In some cases, composition (using objects as attributes) might be a better approach.
Conclusion
Python inheritance is a powerful mechanism for creating hierarchical class relationships and promoting code reuse. By understanding the different types of inheritance and how to properly use the super()
function, you can design more efficient and organized object-oriented programs. Remember to use inheritance judiciously and consider composition as an alternative when appropriate.
The examples provided in this article demonstrate the core concepts of inheritance in Python, giving you a solid foundation to implement these techniques in your own projects.