2.1.8 · HinglishOOP Fundamentals

Inheritance — single inheritance, method resolution order (MRO)

1,956 words9 min readRead in English

2.1.8 · Coding › OOP Fundamentals


Inheritance EXISTS kyun karta hai?

Key relationship is-a hai (na ki has-a).

  • Ek Car ek Vehicle hai → inheritance.
  • Ek Car ke paas ek Engine hai → composition (ek field, na ki parent).

Single Inheritance KYA hai?

class Animal:                 # parent / base / superclass
    def __init__(self, name):
        self.name = name
    def speak(self):
        return "..."
 
class Dog(Animal):            # child / derived / subclass
    def speak(self):          # OVERRIDE
        return "Woof"
 
d = Dog("Rex")
print(d.name)      # 'Rex'   -> inherited __init__ from Animal
print(d.speak())   # 'Woof'  -> overridden in Dog
class Puppy(Dog):
    def speak(self):
        base = super().speak()        # 'Woof' from Dog
        return base + " (tiny)"       # extend it

Python method kaise dhundhta hai? — The MRO

Single inheritance ke liye MRO literally chain hai:

object hamesha last hota hai — yeh har Python class ki root hai.

Figure — Inheritance — single inheritance, method resolution order (MRO)

Lookup algorithm scratch se derive karna

Jab tum obj.speak() likhte ho, Python conceptually karta hai:

  1. T = type(obj) lo.
  2. order = T.__mro__ compute karo (precomputed list).
  3. order mein har class K ke liye order mein:
    • agar 'speak' K.__dict__ mein hai → K.__dict__['speak'] use karo, ruk jao.
  4. Agar kuch nahi mila → AttributeError.

Bus yahi hai — koi magic nahi. super() ka matlab simply hai "wahi search karo, lekin MRO mein current class ke baad wali position se shuru karo."


Worked Example 1 — basic chain

class A:
    def who(self): return "A"
class B(A):
    pass
class C(B):
    def who(self): return "C"
 
c = C()
print(C.__mro__)   # (C, B, A, object)
print(c.who())     # 'C'

(C, B, A, object) kyun? Single inheritance → bas parent chain, phir object. Yeh step kyun? C sabse specific hai isliye pehle hai; object sab kuch root karta hai isliye last hai.

c.who() == 'C' kyun? Search order hai C, B, A, object. C who define karta hai → pehla match → ruk jao. Yeh step kyun? B ke paas who nahi hai, lekin hum wahan pahunchte hi nahi kyunki C pehle match kar gaya.


Worked Example 2 — inheritance gap fill karta hai

b = B()
print(b.who())     # 'A'

'A' kyun? B.__mro__ = (B, A, object). B ke paas who nahi, A ke paas hai. Yeh step kyun? Lookup tab tak walk karta rehta hai jab tak koi class name define na kare; B skip ho jaata hai, A jeet jaata hai.


Worked Example 3 — super() extend karne ke liye, replace karne ke liye nahi

class Account:
    def __init__(self, balance):
        self.balance = balance
    def describe(self):
        return f"balance={self.balance}"
 
class Savings(Account):
    def __init__(self, balance, rate):
        super().__init__(balance)     # run parent's __init__
        self.rate = rate
    def describe(self):
        return super().describe() + f", rate={self.rate}"
 
s = Savings(100, 0.05)
print(s.describe())   # 'balance=100, rate=0.05'

super().__init__ kyun call karein? Kyunki Account.__init__ self.balance set karta hai. Agar hum isko skip karein, self.balance kabhi exist nahi karega. Yeh step kyun? Child ki zimmedari hai ki woh object ke parent wale hisse ko initialize kare.

super().describe() Account wali version kyun deta hai? Savings ke andar super() lookup Savings ke baad wali class se start karta hai MRO (Savings, Account, object) mein → woh hai Account. Yeh step kyun? super() hai "next in MRO", "literal parent" nahi — single inheritance ke liye yeh dono same hote hain.


Worked Example 4 — Forecast-then-Verify



The 80/20 — jo actually matter karta hai


Active Recall

Recall

class C(B), class B(A) ka MRO kya hai? (C, B, A, object) — single-inheritance chain plus object.

Recall Ek inherited method ke andar,

self.foo() kis class ke against resolve hota hai? type(self).__mro__ ke against — object ka dynamic type, na ki woh class jahan method ka code likha hai.

Recall Child ke

__init__ mein super().__init__() call kyun karna zaroori hai? Child mein __init__ define karna parent ka replace kar deta hai; parent ki initialization (jaise fields set karna) tab tak nahi chalegi jab tak tum explicitly isko call na karo.

Recall is-a vs has-a?

is-a → inheritance (Car is-a Vehicle). has-a → composition (Car has-a Engine, ek field ke roop mein).


Recall 🧒 Feynman: ek 12-saal ke bachche ko samjhao

Classes ko recipe cards ki tarah socho. Ek "Dog" recipe card kehta hai "Main bilkul 'Animal' recipe jaisa hoon, bas main '...' ki jagah bark karta hoon." Jab tum dog se kuch karne ko kehte ho, tum cards ko sabse specific se flip karte ho (Dog), phir Animal, phir super-general "object" card, aur jo pehla card uss action ka zikr kare woh karo. Cards ka woh ordered stack MRO hai. super() ka matlab bas hai "mera apna card skip karo aur neeche wala check karo."


Connections

Single inheritance matlab ek class kitne direct parents se derive hoti hai?
Exactly one.
MRO ka full form kya hai aur yeh kya hota hai?
Method Resolution Order — ordered list of classes jo Python method/attribute resolve karne ke liye search karta hai.
class C(B) aur class B(A) ke liye, C.__mro__ kya hai?
(C, B, A, object).
Kisi bhi MRO mein hamesha last class kaun hoti hai?
object, sabhi classes ki root.
Lookup rule: ek name kahan resolve hota hai?
MRO mein pehli class pe jo apne __dict__ mein woh name define karti hai.
super() operationally kya matlab hai?
Attribute lookup MRO mein current class ke turant BAAD wali class se start karo.
Ek inherited method ke andar, self.x() kis class use karke resolve hota hai?
type(self) — object ka dynamic type (polymorphism).
Override vs extend a method?
Override = poori tarah replace karo; Extend = super().method() call karo phir behavior add karo.
Agar ek child __init__ define kare, toh kya parent ka automatically run hota hai?
Nahi — tumhe explicitly super().__init__(...) call karna hoga.
is-a vs has-a guideline?
is-a → inheritance use karo; has-a → composition use karo (ek field).
Jab relationship is-a nahi hai toh composition prefer kyun karein?
Inheritance parent ka poora interface/contract child pe force karta hai, tight coupling aur unwanted methods leak karta hai.

Concept Map

lets

reuses & specializes

requires

else use

simplest form

exactly one parent

replaces method

calls parent then adds

uses

walks

first match wins

MRO is parent chain

Inheritance

Parent class

Child class

is-a relationship

Composition

Single inheritance

Override method

Extend via super

Method Resolution Order

Method lookup