1. Introduction: Advanced Code Reusability via Inheritance
Throughout earlier modules, our primary focus has centered on writing modular code and maximizing reusability. In Object-Oriented Programming (OOP), the most advanced and central mechanism for code reusability is Inheritance.
The word inheritance translates conceptually to "heritage" or "legacy". In programming:
- Once you design a well-structured class complete with its own data attributes and methods, you do not need to rewrite that logic from scratch when building new, related classes.
- Instead, newer classes can directly inherit the data and behaviors of that existing class, creating a natural hierarchy between Parent (Base) classes and Child (Derived) classes.
2. The Real-World Analogy: The Animal Kingdom
Consider modeling the animal world in software:
- Every animal shares fundamental characteristics and behaviors—such as the ability to speak/produce sounds, move around, eat, drink, and reproduce.
- When creating classes for specific animals—such as a Lion, a Dog, or a Cat—each of these is essentially an animal.
- Consequently, all specific animals should automatically possess standard default animal behaviors, while retaining their own unique actions.
- It makes architectural sense to define general animal behaviors inside a common
Animal parent class, and then allow specific animal classes to inherit from it.
3. Python Inheritance Syntax: Parent in Parentheses
To establish inheritance in Python, declare the child class using the class keyword, specify the child class name, and place the parent class name inside parentheses () directly after the child class name:
class ChildClassName(ParentClassName):
Passing the parent class inside parentheses instructs Python to automatically make all data attributes and methods from the parent class accessible within the child class.
4. Example 1: Basic Inheritance and the pass Keyword
In this first example, an Animal parent class defines a general speak() method that prints "some sound". The Dog child class inherits from Animal without defining any new methods of its own yet:
# 1. Defining the Parent (Base) Class
class Animal:
def speak(self):
print("some sound")
# 2. Defining the Child Class inheriting from Animal
class Dog(Animal):
pass
Understanding the pass Keyword
- When defining a class or function where you do not wish to add additional code or custom behaviors yet, Python requires a non-empty indented body.
- The
pass keyword acts as a syntactical placeholder. It executes no operation and causes no effect, allowing the template to compile cleanly while signaling that no further instructions are written yet.
Testing the Inherited Method in Jupyter Notebook
# Instantiating an object of the child class
dog1 = Dog()
# Calling the speak() method on the child object
dog1.speak()
Output:
some sound
How Python Evaluates This
- Notice that
speak() was never defined inside the Dog class.
- Because
Dog inherits from Animal, Python looks inside Dog and, upon finding no local speak() method, ascends the hierarchy to the parent Animal class.
- It finds and executes
Animal.speak(), outputting "some sound".
5. Example 2: Extending the Child Class with Custom Behaviors
Child classes are rarely just empty duplicates; they inherit shared functionality while introducing their own specialized methods.
Here, we extend Dog by adding a child-specific bark() method:
# 1. Parent Class with general functionality
class Animal:
def speak(self):
print("some sound")
# 2. Child Class inheriting from Animal and defining unique behaviors
class Dog(Animal):
def bark(self):
print("woof")
Testing Both Inherited and Child-Specific Methods
# Creating an instance of the modified Dog child class
dog1 = Dog()
# 1. Calling the child's own specific method
dog1.bark()
# 2. Calling the inherited parent method
dog1.speak()
Output:
woof
some sound
Execution Walkthrough
- The
Dog class now possesses two distinct methods: its own specialized bark() method and the inherited speak() method from Animal.
- Calling
dog1.bark() executes the method defined inside Dog, printing "woof".
- Calling
dog1.speak() accesses the method inherited from Animal, printing "some sound".
- This design eliminates redundant code while allowing subclasses to expand their capabilities cleanly.