Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

๐ŸŸข Beginner๐Ÿ”ต Advanced
Classes & ObjectsMethods & SelfInstance VariablesClass VariablesConstructors & InitializationInheritance BasicsPolymorphismEncapsulationMagic Methods & Dunder
Python/Oop/Inheritance Basics

๐ŸŒณ Inheritance Basics โ€” Code Reuse Through Class Hierarchy

Inheritance allows you to create new classes based on existing ones. A child class inherits attributes and methods from a parent class, reducing code duplication and creating logical class hierarchies. Inheritance is one of the core principles of object-oriented programming.


๐ŸŽฏ What is Inheritance?

Inheritance is a mechanism where a new class (child/subclass) inherits attributes and methods from an existing class (parent/superclass). This allows you to reuse code and create specialized versions of more general classes.

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

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

# Dog inherits from Animal
class Dog(Animal):
    pass  # Dog automatically has all of Animal's methods

# Create and use
dog = Dog("Buddy")
print(dog.speak())  # Output: Buddy makes a sound

๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Parent and Child Classes

A parent class (also called base class or superclass) contains common attributes and methods. A child class (also called derived class or subclass) extends the parent class by adding or overriding methods. Child classes specify their parent in parentheses.

class Vehicle:
    def __init__(self, brand, color):
        self.brand = brand
        self.color = color

    def display_info(self):
        return f"{self.color} {self.brand}"

    def drive(self):
        return f"{self.brand} is driving"

class Car(Vehicle):
    def __init__(self, brand, color, doors):
        super().__init__(brand, color)  # Call parent constructor
        self.doors = doors

    def display_info(self):
        return f"{super().display_info()} with {self.doors} doors"

car = Car("Toyota", "blue", 4)
print(car.display_info())  # Output: blue Toyota with 4 doors
print(car.drive())         # Output: Toyota is driving

๐Ÿ”„ Method Overriding

Method overriding allows a child class to provide its own implementation of a method from the parent class. The child's version replaces the parent's version when called on a child object.

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

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

class Dog(Animal):
    def speak(self):  # Override parent's method
        return f"{self.name} barks: Woof!"

class Cat(Animal):
    def speak(self):  # Override parent's method
        return f"{self.name} meows: Meow!"

class Bird(Animal):
    def speak(self):  # Override parent's method
        return f"{self.name} chirps: Tweet!"

# Each child class has its own speak behavior
dog = Dog("Buddy")
cat = Cat("Whiskers")
bird = Bird("Tweety")

print(dog.speak())    # Output: Buddy barks: Woof!
print(cat.speak())    # Output: Whiskers meows: Meow!
print(bird.speak())   # Output: Tweety chirps: Tweet!

๐Ÿ”— Using super()

The `super()` function lets you call methods from the parent class. This is useful when you want to extend parent behavior rather than completely replace it.

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

    def get_info(self):
        return f"{self.name}: ${self.salary}"

class Manager(Employee):
    def __init__(self, name, salary, team_size):
        super().__init__(name, salary)  # Call parent constructor
        self.team_size = team_size

    def get_info(self):
        # Extend parent's get_info
        parent_info = super().get_info()
        return f"{parent_info}, manages {self.team_size} people"

manager = Manager("Alice", 100000, 5)
print(manager.get_info())
# Output: Alice: $100000, manages 5 people

๐Ÿ“Š Inheritance Hierarchies

You can create multi-level hierarchies where a class inherits from another class that also inherits. This creates a chain of inheritance.

class LivingBeing:
    def __init__(self, name):
        self.name = name

    def alive(self):
        return f"{self.name} is alive"

class Animal(LivingBeing):
    def move(self):
        return f"{self.name} moves"

class Mammal(Animal):
    def warm_blooded(self):
        return f"{self.name} is warm-blooded"

class Dog(Mammal):
    def bark(self):
        return f"{self.name} barks"

dog = Dog("Buddy")
print(dog.alive())          # From LivingBeing
print(dog.move())           # From Animal
print(dog.warm_blooded())   # From Mammal
print(dog.bark())           # From Dog

๐ŸŽ Adding New Methods

Child classes can add completely new methods that the parent doesn't have. This allows you to extend functionality beyond what the parent provides.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        return f"I'm {self.name}, {self.age} years old"

class Doctor(Person):
    def __init__(self, name, age, specialty):
        super().__init__(name, age)
        self.specialty = specialty

    # Parent methods are inherited
    def introduce(self):
        parent_intro = super().introduce()
        return f"{parent_intro}, I'm a {self.specialty} doctor"

    # New methods unique to Doctor
    def prescribe_medicine(self, medicine):
        return f"I prescribe {medicine}"

    def diagnose(self, symptom):
        return f"For {symptom}, come back in 3 days"

doctor = Doctor("Dr. Smith", 45, "Cardiologist")
print(doctor.introduce())
print(doctor.prescribe_medicine("Aspirin"))
print(doctor.diagnose("chest pain"))

๐Ÿ“š Real-World Examples

Bank Account Inheritance

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount
        return f"Deposited ${amount}"

    def withdraw(self, amount):
        if amount <= self.balance:
            self.balance -= amount
            return f"Withdrew ${amount}"
        return "Insufficient funds"

    def get_balance(self):
        return f"Balance: ${self.balance}"

class SavingsAccount(BankAccount):
    def __init__(self, owner, balance, interest_rate):
        super().__init__(owner, balance)
        self.interest_rate = interest_rate

    def apply_interest(self):
        interest = self.balance * self.interest_rate
        self.balance += interest
        return f"Interest added: ${interest:.2f}"

class CheckingAccount(BankAccount):
    def __init__(self, owner, balance, overdraft_limit):
        super().__init__(owner, balance)
        self.overdraft_limit = overdraft_limit

    def withdraw(self, amount):
        if amount <= self.balance + self.overdraft_limit:
            self.balance -= amount
            return f"Withdrew ${amount}"
        return "Exceeds overdraft limit"

savings = SavingsAccount("Alice", 1000, 0.05)
print(savings.deposit(500))
print(savings.apply_interest())
print(savings.get_balance())

checking = CheckingAccount("Bob", 500, 200)
print(checking.withdraw(600))  # More than balance but within overdraft
print(checking.get_balance())

Game Character Classes

class Character:
    def __init__(self, name, level):
        self.name = name
        self.level = level
        self.health = 100

    def take_damage(self, damage):
        self.health -= damage
        return f"{self.name} took {damage} damage"

    def level_up(self):
        self.level += 1
        self.health = 100
        return f"{self.name} leveled up to {self.level}"

class Warrior(Character):
    def __init__(self, name, level):
        super().__init__(name, level)
        self.armor = 50

    def shield_bash(self):
        return f"{self.name} uses Shield Bash!"

    def take_damage(self, damage):
        reduced_damage = max(1, damage - self.armor)
        return super().take_damage(reduced_damage)

class Mage(Character):
    def __init__(self, name, level):
        super().__init__(name, level)
        self.mana = 100

    def fireball(self):
        if self.mana >= 20:
            self.mana -= 20
            return f"{self.name} casts Fireball!"
        return "Not enough mana"

warrior = Warrior("Aragorn", 10)
mage = Mage("Gandalf", 10)

print(warrior.take_damage(30))  # Armor reduces damage
print(warrior.shield_bash())

print(mage.fireball())
print(mage.fireball())
print(mage.fireball())  # Will run out of mana

โœ… Key Takeaways

ConceptRemember
InheritanceCreate new classes based on existing ones
Parent ClassThe class being inherited from (base class)
Child ClassThe class that inherits (subclass)
super()Call parent class methods from child
Method OverridingChild class provides its own implementation
HierarchyClasses can inherit from other subclasses
Code ReuseAvoid repeating code by using inheritance
is-a RelationshipChild "is-a" type of parent

๐Ÿ”— What's Next?

Now let's learn about polymorphism, which allows different objects to be used interchangeably.

Next: Polymorphism โ†’


Ready to practice? Try challenges or explore more concepts


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep โ€ข Build Real โ€ข Verify Skills โ€ข Launch Forward

Courses

PythonFastapiReactJSCloud

ยฉ 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn