Python20 min read

Python Inheritance

Learn inheritance step by step: parent vs child classes, method overriding, super(), and safe patterns used in real projects.

Michael Brown
July 21, 2025
11.6k489

Inheritance is an OOP feature that lets one class reuse and extend another class.

  Think of it like a blueprint:
  - A **parent class** defines common behavior.
  - A **child class** inherits it, then adds or changes what it needs.
  
  Inheritance solves a real problem:
  When you have multiple classes that share the same logic, you do not want to copy-paste that logic everywhere.
  
  ## When inheritance is a good idea (and when it is not)
  
  Inheritance is good when:
  - classes share a clear "is-a" relationship  
    Example: Dog is an Animal, Car is a Vehicle
  
  Inheritance is not ideal when:
  - the relationship is "has-a"  
    Example: A Car has an Engine (composition is better)
  
  If you are unsure, start with simple classes. Use inheritance only when the relationship is natural.
  
  ## Basic inheritance (parent and child)
  
  ```python
  class Animal:
      def __init__(self, name):
          self.name = name
  
      def speak(self):
          print("Some sound")
  
  class Dog(Animal):
      def speak(self):
          print(f"{self.name} says Woof!")
  
  class Cat(Animal):
      def speak(self):
          print(f"{self.name} says Meow!")
  
  dog = Dog("Max")
  cat = Cat("Whiskers")
  
  dog.speak()
  cat.speak()
  ```
  
  Expected output:
  
  ```
  Max says Woof!
  Whiskers says Meow!
  ```
  
  ### What happened here?
  
  - `Dog` and `Cat` **inherit** `name` from `Animal`
  - They **override** `speak()` so each animal speaks differently
  
  ## Method overriding (same method name, different behavior)
  
  If the child defines a method with the same name as the parent, the child version runs.
  
  ```python
  class Animal:
      def speak(self):
          print("Some sound")
  
  class Dog(Animal):
      def speak(self):
          print("Woof!")
  
  Dog().speak()
  ```
  
  Expected output:
  
  ```
  Woof!
  ```
  
  ## Using super() correctly
  
  `super()` lets the child call the parent’s version of a method. This is extremely common in real code for constructors.
  
  ```python
  class Vehicle:
      def __init__(self, brand):
          self.brand = brand
  
      def info(self):
          print(f"Brand: {self.brand}")
  
  class Car(Vehicle):
      def __init__(self, brand, model):
          super().__init__(brand)   # initialize parent part
          self.model = model        # initialize child part
  
      def info(self):
          super().info()            # parent info
          print(f"Model: {self.model}")
  
  car = Car("Tesla", "Model 3")
  car.info()
  ```
  
  Expected output:
  
  ```
  Brand: Tesla
  Model: Model 3
  ```
  
  ## Multiple inheritance (use carefully)
  
  Python allows a class to inherit from multiple parents. This is powerful but can get confusing if overused.
  
  ```python
  class Walker:
      def walk(self):
          print("Walking...")
  
  class Swimmer:
      def swim(self):
          print("Swimming...")
  
  class Duck(Walker, Swimmer):
      pass
  
  duck = Duck()
  duck.walk()
  duck.swim()
  ```
  
  Expected output:
  
  ```
  Walking...
  Swimming...
  ```
  
  ## Graph: inheritance structure
  
  ```mermaid
  classDiagram
    Animal <|-- Dog
    Animal <|-- Cat
    class Animal {
      +name
      +speak()
    }
    class Dog {
      +speak()
    }
    class Cat {
      +speak()
    }
  ```
  
  ## Common beginner mistakes
  
  - Using inheritance just to “reuse code” without a real relationship
  - Forgetting to call `super().__init__()` in the child class
  - Making deep inheritance chains (hard to maintain)
  
  A good rule:
  Keep inheritance shallow and readable. If your class tree looks like a family tree with 10 generations, it will be hard to debug.
  
  In the next lesson, you will learn JSON handling, which is one of the most practical skills for API work in Python.
#Python#Intermediate#OOP