Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Inheritance in Python

What is Inheritance?

Inheritance allows a class (child) to acquire the attributes and methods of another class (parent). It promotes code reuse and models real-world "is-a" relationships.

  • Child class inherits all parent attributes and methods
  • Child can add new attributes and methods
  • Child can override parent methods
  • Use super() to call parent methods

Single Inheritance

Single Inheritance
class Animal:
    def __init__(self, name: str, sound: str):
        self.name = name
        self.sound = sound

    def speak(self) -> str:
        return f"{self.name} says {self.sound}"

    def describe(self) -> str:
        return f"I am {self.name}"

# Dog inherits from Animal
class Dog(Animal):
    def __init__(self, name: str, breed: str):
        super().__init__(name, "Woof")   # call parent __init__
        self.breed = breed

    def fetch(self) -> str:
        return f"{self.name} fetches the ball!"

dog = Dog("Buddy", "Labrador")
print(dog.speak())     # Buddy says Woof  (inherited)
print(dog.describe())  # I am Buddy       (inherited)
print(dog.fetch())     # Buddy fetches the ball! (own method)
print(dog.breed)       # Labrador

# isinstance checks
print(isinstance(dog, Dog))     # True
print(isinstance(dog, Animal))  # True — Dog IS-A Animal

Method Overriding

Overriding Methods
class Shape:
    def area(self) -> float:
        return 0.0

    def describe(self) -> str:
        return f"Shape with area {self.area():.2f}"

class Circle(Shape):
    def __init__(self, radius: float):
        self.radius = radius

    def area(self) -> float:          # override parent method
        import math
        return math.pi * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, width: float, height: float):
        self.width = width
        self.height = height

    def area(self) -> float:          # override parent method
        return self.width * self.height

c = Circle(5)
r = Rectangle(4, 6)

print(c.area())       # 78.54
print(r.area())       # 24.0
print(c.describe())   # Shape with area 78.54 (uses overridden area())
print(r.describe())   # Shape with area 24.00

super() — Calling Parent Methods

super()
class Employee:
    def __init__(self, name: str, salary: float):
        self.name = name
        self.salary = salary

    def get_info(self) -> str:
        return f"{self.name} — ${self.salary:,.0f}/yr"

class Manager(Employee):
    def __init__(self, name: str, salary: float, team_size: int):
        super().__init__(name, salary)   # extend parent __init__
        self.team_size = team_size

    def get_info(self) -> str:
        base = super().get_info()        # extend parent method
        return f"{base} | Team: {self.team_size}"

class Director(Manager):
    def __init__(self, name: str, salary: float, team_size: int, budget: float):
        super().__init__(name, salary, team_size)
        self.budget = budget

    def get_info(self) -> str:
        base = super().get_info()
        return f"{base} | Budget: ${self.budget:,.0f}"

d = Director("Alice", 150000, 20, 5000000)
print(d.get_info())
# Alice — $150,000/yr | Team: 20 | Budget: $5,000,000

Multiple Inheritance

Multiple Inheritance
class Flyable:
    def fly(self) -> str:
        return "I can fly!"

class Swimmable:
    def swim(self) -> str:
        return "I can swim!"

class Duck(Flyable, Swimmable):
    def quack(self) -> str:
        return "Quack!"

duck = Duck()
print(duck.fly())    # I can fly!
print(duck.swim())   # I can swim!
print(duck.quack())  # Quack!

# MRO — Method Resolution Order
# Python uses C3 linearization to resolve method lookup order
print(Duck.__mro__)
# (<class 'Duck'>, <class 'Flyable'>, <class 'Swimmable'>, <class 'object'>)

# Mixins — common pattern for multiple inheritance
class LogMixin:
    def log(self, message: str):
        print(f"[{self.__class__.__name__}] {message}")

class JsonMixin:
    def to_json(self) -> str:
        import json
        return json.dumps(self.__dict__)

class User(LogMixin, JsonMixin):
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

u = User("Alice", 25)
u.log("User created")   # [User] User created
print(u.to_json())      # {"name": "Alice", "age": 25}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.