← Back to Blog

Reusing Code with Inheritance

The problem...

You have an Animal class. It works well for the Safe Paws shelter — name, species, size, health, status.

Now you want a Dog class and a Cat class. Dogs have a breed. Cats have an indoor/outdoor preference. Both still have a name, species, age, health, status.

You could write two separate classes from scratch. But most of the code would be identical. Every change to the shared logic would require updating both classes. That's not reuse — that's duplication.

The idea!

Inheritance lets one class — the child — inherit all the attributes and methods of another class — the parent. The child gets everything the parent has, and can add its own on top.

Write the shared logic once. Let every child class inherit it.

Making it real

class Animal:
    def __init__(self, name, species, age):
        self.name    = name
        self.species = species
        self.age     = age
        self.status  = "available"

    def describe(self):
        print(f"{self.name} is a {self.age} year old {self.species}.")

    def adopt(self):
        self.status = "adopted"
        print(f"{self.name} has been adopted!")

Now a Dog class that inherits from Animal:

class Dog(Animal):
    def __init__(self, name, age, breed):
        super().__init__(name, "dog", age)
        self.breed = breed

    def fetch(self):
        print(f"{self.name} fetches the ball!")
lassie = Dog("Lassie", 4, "Collie")

print(lassie.name)      # Lassie  — inherited from Animal
print(lassie.breed)     # Collie  — Dog's own attribute
print(lassie.status)    # available — inherited from Animal

lassie.describe()       # Lassie is a 4 year old dog. — inherited method
lassie.adopt()          # Lassie has been adopted! — inherited method
lassie.fetch()          # Lassie fetches the ball! — Dog's own method

Dog inherits everything from Animal — and adds its own breed attribute and fetch method.

super()

super().__init__() calls the parent's constructor. Without it, Animal.__init__ never runs — and name, age, status are never set.

class Dog(Animal):
    def __init__(self, name, age, breed):
        super().__init__(name, "dog", age)    # runs Animal.__init__
        self.breed = breed                     # Dog's own addition

Think of it as: "Do everything the parent does first, then add what's specific to me."

A second child class

class Cat(Animal):
    def __init__(self, name, age, indoor):
        super().__init__(name, "cat", age)
        self.indoor = indoor    # True or False

    def describe(self):
        location = "indoor" if self.indoor else "outdoor"
        print(f"{self.name} is a {self.age} year old {location} cat.")
whiskers = Cat("Whiskers", 2, True)

whiskers.describe()     # Whiskers is a 2 year old indoor cat. — overridden
whiskers.adopt()        # Whiskers has been adopted! — inherited from Animal

Cat overrides describe() with its own version. Animal's describe() is replaced — but only for Cat objects. Dog still uses the original.

Checking inheritance

print(isinstance(lassie, Dog))      # True
print(isinstance(lassie, Animal))   # True  — Dog is an Animal
print(isinstance(lassie, Cat))      # False

isinstance() checks if an object is an instance of a class — or any of its parent classes. A Dog is also an Animal.

Heads up!

  • The child class name goes in parentheses: class Dog(Animal):
  • Always call super().__init__() in the child's constructor — or parent attributes won't exist
  • A child can override any parent method by defining it again
  • A child can add new attributes and methods that the parent doesn't have
  • The parent class is unchanged — inheritance doesn't modify it

The mindset shift

Stop thinking: "I'll copy the class and modify it."

Start thinking: "I'll inherit the shared logic and only define what's different."

What you should understand now

  • Inheritance lets a child class reuse all attributes and methods of a parent class
  • class Child(Parent): — the syntax for inheritance
  • super().__init__() calls the parent's constructor
  • A child can override parent methods by redefining them
  • A child can add new attributes and methods
  • isinstance(obj, Class) returns True for the object's class and all its parents
[ login to bookmark ] // copied! 30 views · 3 min
// resources
Code Example oop_inheritance.py
← prev Encapsulation: Control Over Your Data next → Polymorphism: When the Same Call Does Different Things
// 0 comments
// No comments yet. Be the first.
// leave a comment

// Your comment will appear after approval.