DEV Community

Deepika Pusala
Deepika Pusala

Posted on

Week 4, Task - 1.1: Classes, Inheritance & MRO 🐍

Object-Oriented Programming sounds intimidating until you realize it's really just... family trees and blueprints. Let's break down three concepts that trip up almost everyone at first: classes, inheritance, and MRO.


🧱 What Is a Class?

A class is a blueprint. An object is the real thing built from that blueprint.

Think of a company that hires employees. Every employee has a name, age, and salary, and can work(). Instead of writing that logic separately for each person, you define it once:

class Employee:
    def work(self):
        print("Employee is working")

e1 = Employee()
e2 = Employee()
Enter fullscreen mode Exit fullscreen mode
Term Meaning
Class The design/template
Object An actual instance created from that template

Quick answer for interviews: "A class defines the attributes and methods its objects will have. An object is an instance of that class."


🧬 What Is Inheritance?

Inheritance lets a child class reuse the attributes and methods of a parent class β€” and add its own on top.

class Animal:
    def eat(self):
        print("Animal is eating")

class Dog(Animal):
    def bark(self):
        print("Dog is barking")
Enter fullscreen mode Exit fullscreen mode
Animal
   ↑
   |
  Dog
Enter fullscreen mode Exit fullscreen mode

A Dog object can call both bark() and eat() β€” the second one comes free, inherited from Animal.

Why bother? Without it, you'd repeat the same eat()/sleep() code in every animal class. Inheritance = write once, reuse everywhere, specialize as needed.


🌳 The 5 Types of Inheritance

Type Shape Example
Single A β†’ B One parent, one child
Multilevel A β†’ B β†’ C Grandparent β†’ Parent β†’ Child
Hierarchical A β†’ B and A β†’ C One parent, many children
Multiple A + B β†’ C One child, many parents
Hybrid Mix of the above Combines two or more patterns

A quick real-world flavor:

class Animal:
    def eat(self): print("Eating")

class Machine:
    def charge(self): print("Charging")

class Robot(Animal, Machine):   # Multiple inheritance
    pass
Enter fullscreen mode Exit fullscreen mode

Robot can now both eat() and charge() β€” pulling from two separate parents.


πŸ”„ Overriding vs βž• Overloading (don't mix these up!)

Concept Meaning Works in Python?
Overriding Child redefines a method that already exists in the parent, giving it new behavior βœ… Yes
Overloading Same method name, different parameter lists (like Java) ❌ Not directly

Overriding example:

class Animal:
    def sound(self): print("Animal makes sound")

class Dog(Animal):
    def sound(self): print("Dog barks")   # overrides parent
Enter fullscreen mode Exit fullscreen mode

About overloading: Python doesn't support true overloading β€” defining add() twice just replaces the first version. Instead, we fake it with default arguments or *args:

class Calculator:
    def add(self, a, b, c=0):
        return a + b + c
Enter fullscreen mode Exit fullscreen mode

🧭 MRO: Method Resolution Order

MRO is just Python's rule for which class to check first when looking for a method β€” especially useful once multiple parents are involved.

Child
  ↓
Parent
  ↓
Grandparent
  ↓
object
Enter fullscreen mode Exit fullscreen mode

Python always starts the search at the object's own class and works upward. object sits at the very end β€” it's the ultimate base class every Python class inherits from, even implicitly.

Check it yourself:

print(Dog.mro())
# or
print(Dog.__mro__)
Enter fullscreen mode Exit fullscreen mode

Where it really matters: multiple inheritance

class Bangalore:
    def show(self):
        print("Bangalore")

class Vizag(Bangalore):
    def show(self):
        print("Vizag")

class Hyderabad(Bangalore):
    def show(self):
        print("Hyderabad")

class Chennai(Hyderabad, Vizag):
    pass

city = Chennai()
city.show()
print(Chennai.mro())
Enter fullscreen mode Exit fullscreen mode
Hyderabad
[<class 'Chennai'>, <class 'Hyderabad'>, <class 'Vizag'>, <class 'Bangalore'>, <class 'object'>]
Enter fullscreen mode Exit fullscreen mode

Chennai itself has no show(), so Python walks the MRO left to right: Chennai → Hyderabad → Vizag→ Bangalore → object. It hits Hyderabad first (since it's listed first in class Chennai(Hyderabad, Vizag)) and stops there — that's why the output is "Hyderabad", not "Vzag" or "Bangalore".


πŸͺœ super() β€” jump to the next class in line

super() tells Python: "go to the next class in the MRO and use its version of this method." If you skip it, the parent's version simply never runs.

class Animal:
    def speak(self):
        print("Animal speaks")

class Dog(Animal):
    def speak(self):
        # super().speak()
        print("Dog barks")

d = Dog()
d.speak()
Enter fullscreen mode Exit fullscreen mode
Dog barks
Enter fullscreen mode Exit fullscreen mode

Because super().speak() is commented out, Animal's speak() never gets called β€” Python only runs Dog's overridden version. Uncomment that line and you'd get both lines:

Animal speaks
Dog barks
Enter fullscreen mode Exit fullscreen mode

🏒 A Real-World Flavor

User roles in an e-commerce app:

                User
              /      \
        Customer     Seller β†’ Admin
Enter fullscreen mode Exit fullscreen mode

All roles share login()/logout() from User, while adding their own methods (buy_product(), add_product(), etc.).

Payment systems are a classic overriding example:

class Payment:
    def pay(self): print("Processing payment")

class UPIPayment(Payment):
    def pay(self): print("Processing UPI payment")   # overridden
Enter fullscreen mode Exit fullscreen mode

Mixins (common in frameworks) are where MRO quietly does its job:

class LoggingMixin:
    def log(self): print("Logging")

class AuthMixin:
    def authenticate(self): print("Authenticating")

class UserService(LoggingMixin, AuthMixin):
    pass
Enter fullscreen mode Exit fullscreen mode

🎯 Cheat-Sheet Answers

Question Short Answer
What is inheritance? A child class reuses a parent's attributes/methods and can add or override behavior
Why use it? Code reuse + specialization
What is overriding? Child redefines a parent's method with its own implementation
Does Python support overloading? No β€” use default args or *args instead
What is MRO? The order Python searches classes for a method, especially with multiple inheritance
Where does object sit in MRO? Always at the end β€” it's the base of everything
How to check MRO? ClassName.mro() or ClassName.__mro__

πŸ’‘ The Whole Topic, One Breath

A class is a blueprint that makes objects. A child class can use inheritance to reuse a parent's code β€” and if it redefines a method, that's overriding. Python skips true overloading in favor of default arguments. When multiple parents are involved, MRO decides the search order, always ending at object. And super() is your shortcut to the next class in that order.

Top comments (0)