Inheritance and Polymorphism in Python: Reuse, Extend, and Evolve Your Code

Object-Oriented Programming is powerful because it lets us build flexible, reusable systems. Two core principles that unlock this power are:

  • Inheritance – Reuse and extend existing code
  • Polymorphism – Use the same interface for different behaviors

If you’ve ever written the same logic twice with minor changes… or wished to write generic code that can adapt to many types these concepts are for you.

In this guide, you’ll learn:

  • What inheritance and polymorphism mean (in plain English)
  • How to use them in Python with clear examples
  • When to use super() and how to override methods
  • Real-world analogies and gotchas to avoid
  • Best practices and code patterns that scale

Let’s go step by step.


🧬 What is Inheritance?

Inheritance allows one class (called the child or subclass) to inherit properties and behavior from another class (called the parent or superclass).

It promotes code reuse and helps you follow the DRY principle: Don’t Repeat Yourself.


📦 Real-Life Analogy

Imagine a Vehicle class. A Car and a Bike are both vehicles. Instead of rewriting everything, Car and Bike can inherit from Vehicle.


🧱 Defining a Parent Class

Python
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print(f"{self.name} makes a sound.")

This is a base class. Now let’s extend it.


🐶 Creating a Child Class

Python
class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # Reuse Animal’s __init__
        self.breed = breed

    def speak(self):
        print(f"{self.name} barks.")

✅ Breakdown:

  • Dog(Animal) means Dog inherits from Animal
  • super().__init__(name) calls the parent constructor
  • You can add new attributes (like breed)
  • You can also override methods (like speak())

🔁 What is Method Overriding?

If the child class defines a method with the same name as one in the parent class, Python uses the child’s version.

Python
a = Animal("Leo")
a.speak()  # Leo makes a sound.

d = Dog("Bruno", "Labrador")
d.speak()  # Bruno barks.

✅ This is method overriding in action.


🧠 Why Use super()?

super() lets you:

  • Reuse logic from the parent class
  • Avoid hardcoding the parent name
  • Work well with multiple inheritance

It looks like:

Python
super().__init__(args)

🧬 What is Polymorphism?

Polymorphism means “many forms.”

In OOP, it lets different classes implement the same method name, and you can call it without knowing the exact class type.


🧪 Example:

Python
class Cat(Animal):
    def speak(self):
        print(f"{self.name} meows.")

animals = [Dog("Bruno", "Labrador"), Cat("Whiskers")]

for animal in animals:
    animal.speak()

Output:
Bruno barks.
Whiskers meows.

✅ Even though Dog and Cat behave differently, we call speak() the same way.
This is polymorphism and it makes your code flexible.


🧱 Real-World Example: Payment Systems

Python
class PaymentProcessor:
    def process(self, amount):
        raise NotImplementedError("Must implement in subclass")

class PayPalProcessor(PaymentProcessor):
    def process(self, amount):
        print(f"Processing ₹{amount} via PayPal")

class StripeProcessor(PaymentProcessor):
    def process(self, amount):
        print(f"Processing ₹{amount} via Stripe")

Now:

Python
def checkout(processor: PaymentProcessor, amount):
    processor.process(amount)

checkout(PayPalProcessor(), 100)
checkout(StripeProcessor(), 200)

✅ This design lets us plug in any processor, without rewriting the checkout logic.


⚠️ Inheritance vs Composition

Inheritance is powerful, but don’t overuse it. If a class “has a” relationship (not “is a”), prefer composition.

E.g., a Car has a GPS (composition)
A Car is a Vehicle (inheritance)


💡 Best Practices

RuleWhy
Use inheritance only when it makes sense (“is-a” relationship)Avoid tight coupling
Always use super() in child constructorsKeeps the parent logic intact
Override only what needs changingAvoid code duplication
Don’t override just to passUse pass or default to parent
Prefer composition over deep inheritanceEasier to test and maintain

🧩 Related Topics


💌 Stay Updated with PyUniverse

Want Python and AI explained simply straight to your inbox?

Join hundreds of curious learners who get:

  • ✅ Practical Python tips & mini tutorials
  • ✅ New blog posts before anyone else
  • ✅ Downloadable cheat sheets & quick guides
  • ✅ Behind-the-scenes updates from PyUniverse

No spam. No noise. Just useful stuff that helps you grow one email at a time.

🛡️ I respect your privacy. You can unsubscribe anytime.

Leave a Comment