Back to Blog
Lesson 47 of the Python: Programming from Zero with Python course
PythonSeptember 4, 20263 min read

Inheritance in Python: Code Reuse and Polymorphism Explained

Master inheritance in Python to build flexible, reusable code. Learn to create subclasses, override methods, and use super() to extend your objects efficiently.

pythonoopinheritanceprogramming-fundamentalssoftware-engineering
Close-up view of a computer screen displaying code in a software development environment.

Previously in this course, we explored Introduction to Object-Oriented Programming (OOP) in Python and solidified our understanding of Methods and Attributes: Mastering OOP State and Behavior. Now that you can build self-contained objects, we will look at how to scale those objects by using inheritance.

Inheritance is a core pillar of object-oriented programming (OOP) that allows you to define a new class based on an existing one. Instead of rewriting logic, you "inherit" attributes and methods from a parent class, letting you focus on what makes your new, specialized class unique.

Why Use Inheritance?

The primary goal of inheritance is code reuse. Imagine you are building a data processing tool that handles different file formats. You might have a base FileHandler class that knows how to open and close files. Instead of writing that logic again for a CSVHandler or JSONHandler, you create subclasses that inherit those base capabilities.

This approach also enables polymorphism, allowing different objects to be treated as instances of the same base class while exhibiting their own unique behaviors.

Creating Subclasses and Using super()

When you define a subclass, you pass the parent class name in parentheses. If you need to add to or change the __init__ method, you use super() to trigger the parent's initialization logic first.

Consider this example where we extend a basic DataProcessor class:

PYTHON
class DataProcessor:
    def __init__(self, source):
        self.source = source
        print(f"Initializing processor for {self.source}")

    def process(self):
        print("Processing generic data...")

class CSVProcessor(DataProcessor):
    def __init__(self, source, delimiter=","):
        # Use super() to call the parent's __init__ method
        super().__init__(source)
        self.delimiter = delimiter

    # Overriding a method
    def process(self):
        print(f"Processing CSV from {self.source} with delimiter CE9178">'{self.delimiter}'")

# Usage
csv_tool = CSVProcessor("data.csv", delimiter=";")
csv_tool.process()

Key Components Explained

  1. Subclass Definition: class CSVProcessor(DataProcessor) tells Python that CSVProcessor is a child of DataProcessor.
  2. super(): This function provides a proxy to the parent class. It ensures that the parent's __init__ logic (like setting self.source) runs, preventing you from duplicating that assignment code in the child.
  3. Method Overriding: By defining a process method inside CSVProcessor, we replace the version provided by the parent. This allows the same method name to perform different actions depending on the object type.

Hands-on Exercise

In our ongoing project, we need to handle different storage backends. Create a base class named Storage with a method save(data). Then, create a subclass named JSONStorage that inherits from Storage and overrides the save method to print a message like: "Saving data to JSON: {data}".

Common Pitfalls

  • Forgetting super(): If you override __init__ without calling super().__init__(), the parent class's initialization logic is skipped, which often leads to AttributeError when the parent's attributes aren't defined.
  • Deep Inheritance Hierarchies: While you can inherit multiple levels deep (e.g., A -> B -> C), avoid going too deep. It makes code difficult to trace and understand. Stick to one or two levels of depth whenever possible.
  • Misusing Inheritance: Not everything needs to be a subclass. If you just need a utility function, a standalone function is often better than forcing a class structure.

FAQ

Q: Can a subclass have more methods than its parent? A: Yes! You can add as many new methods and attributes as you need to a subclass.

Q: What is the difference between overriding and extending? A: Overriding replaces a parent method with a new version. Extending involves adding new methods or attributes that the parent class didn't have.

Q: Does Python support multiple inheritance? A: Yes, Python allows a class to inherit from multiple parents, but it can introduce complexity. As a beginner, stick to single inheritance until you are comfortable with how it works.

Recap

Inheritance is the "is-a" relationship in programming. By creating subclasses, you leverage existing code to build specialized tools efficiently. Using super() keeps your initialization clean, and method overriding allows your classes to behave in specific ways while sharing a common interface.

Up next: Project: Class-Based Data Handler, where we'll apply these concepts to organize our data-processing workflow into clean, extensible classes.

Similar Posts