In object-oriented programming (OOP), inheritance is a fundamental concept that allows you to create a new class that inherits properties and behaviors from an existing class. This enables you to create a hierarchy of classes with shared characteristics while promoting code reusability and maintainability. Python, being an object-oriented language, fully supports class inheritance. In this tutorial, we will explore the concept of class inheritance in Python with detailed explanations and examples.
Table of Contents
- Introduction to Class Inheritance
- Base Class and Derived Class
- Inheriting Attributes and Methods
- Overriding Methods
- Accessing Base Class Methods
- Multiple Inheritance
- Method Resolution Order (MRO)
- Using the
super()
Function - Example 1: Basic Class Inheritance
- Example 2: Multiple Inheritance
1. Introduction to Class Inheritance
Inheritance is a principle in OOP where a new class (called a derived or subclass) can inherit properties and behaviors (attributes and methods) from an existing class (called a base or superclass). This relationship promotes code reusability, as the derived class can build upon the functionality of the base class.
2. Base Class and Derived Class
Inheritance involves two main classes: the base class (also known as the parent class or superclass) and the derived class (also known as the child class or subclass). The base class serves as a blueprint, and the derived class extends or specializes its features.
3. Inheriting Attributes and Methods
When a class inherits from another class, it automatically gains access to the attributes and methods defined in the base class. These attributes and methods can be used directly in the derived class.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass # To be overridden in derived classes
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
In the above example, the Animal
class is the base class, and both Dog
and Cat
are derived classes. The derived classes inherit the name
attribute and the speak()
method from the base class.
4. Overriding Methods
Derived classes can provide their own implementation of a method inherited from the base class. This is known as method overriding. When a method is overridden in the derived class, the derived class’s implementation will be used instead of the base class’s implementation.
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Square(Rectangle):
def __init__(self, side_length):
super().__init__(side_length, side_length)
def area(self):
return self.width * self.height # Overridden method
In this example, the Rectangle
class has an area()
method that calculates the area of a rectangle. The Square
class is a derived class that inherits from Rectangle
and overrides the area()
method to calculate the area of a square.
5. Accessing Base Class Methods
In the derived class, you can still access methods from the base class using the instance of the derived class. This can be useful when you want to extend the functionality of the base class’s method.
class Vehicle:
def start_engine(self):
print("Engine started")
class Car(Vehicle):
def start_engine(self):
super().start_engine() # Calling the base class method
print("Car's engine started")
my_car = Car()
my_car.start_engine()
Here, the Car
class overrides the start_engine()
method, but it also calls the base class’s start_engine()
method using the super()
function.
6. Multiple Inheritance
Python supports multiple inheritance, where a derived class can inherit from multiple base classes. This allows you to combine features from different classes.
class A:
def method_a(self):
print("Method A")
class B:
def method_b(self):
print("Method B")
class C(A, B):
def method_c(self):
print("Method C")
obj = C()
obj.method_a() # Calls method from class A
obj.method_b() # Calls method from class B
obj.method_c() # Calls method from class C
In this example, the class C
inherits from both classes A
and B
, allowing it to access methods from both base classes.
7. Method Resolution Order (MRO)
When using multiple inheritance, Python determines the order in which methods are resolved. This order is called the Method Resolution Order (MRO). The MRO is important to ensure that methods are inherited and overridden correctly.
class X:
def method(self):
print("Method of class X")
class Y(X):
def method(self):
print("Method of class Y")
class Z(X):
def method(self):
print("Method of class Z")
class W(Y, Z):
pass
obj = W()
obj.method() # Prints "Method of class Y"
In this example, the W
class inherits from both classes Y
and Z
. Since Y
comes before Z
in the inheritance chain, the method from class Y
is used.
8. Using the super()
Function
The super()
function is used to call methods from the base class. It’s especially useful when dealing with multiple inheritance, as it helps avoid confusion in method resolution.
class Parent:
def show(self):
print("Parent class method")
class Child(Parent):
def show(self):
super().show() # Calls the method from the parent class
print("Child class method")
obj = Child()
obj.show()
Here, the Child
class uses the super()
function to call the show()
method of the base class before adding its own functionality.
9. Example 1: Basic Class Inheritance
Let’s consider an example involving shapes. We’ll create a base class Shape
with attributes name
and color
, and a derived class Circle
that inherits from Shape
.
class Shape:
def __init__(self, name, color):
self.name = name
self.color = color
def display(self):
return f"{self.color} {self.name}"
class Circle(Shape):
def __init__(self, name, color, radius):
super().__init__(name, color)
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
# Usage
my_circle = Circle("Circle", "Red", 5)
print(my_circle.display()) # Output: Red Circle
print(my_circle.area()) # Output: 78.5
In this example, the Circle
class inherits the attributes name
and color
from the Shape
class and provides its own method area()
to calculate the area of the circle.
10
. Example 2: Multiple Inheritance
Consider a scenario where we have a base class Person
, a base class Employee
, and a derived class Manager
that inherits from both Person
and Employee
.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
return f"{self.name} is {self.age} years old"
class Employee:
def __init__(self, emp_id, salary):
self.emp_id = emp_id
self.salary = salary
def display_salary(self):
return f"Employee ID: {self.emp_id}, Salary: ${self.salary}"
class Manager(Person, Employee):
def __init__(self, name, age, emp_id, salary):
Person.__init__(self, name, age)
Employee.__init__(self, emp_id, salary)
# Usage
manager = Manager("Alice", 35, "M123", 75000)
print(manager.info()) # Output: Alice is 35 years old
print(manager.display_salary()) # Output: Employee ID: M123, Salary: $75000
In this example, the Manager
class inherits from both Person
and Employee
, combining attributes and methods from both base classes.
Conclusion
Class inheritance is a powerful concept in Python’s object-oriented programming paradigm. It allows you to create a hierarchy of classes that share attributes and methods, while also enabling customization and specialization through method overriding. By understanding and effectively using class inheritance, you can write more efficient, maintainable, and reusable code in your projects.