Hum "magically" sahi method nahi paate. Chalte hain mechanism build karte hain.
Har class ek hidden method table maintain karti hai (ek "vtable"): method name → code address ka map.
vtable(C)={m↦most-derived definition of m visible in C}
Shape ki table: area → Shape.area (shayad abstract/empty).
Circle ki table Shape ki table ki copy se shuru hoti hai, phir area → Circle.area ko overwrite karti hai.
Jab tum obj.area() call karte ho:
obj ki actual class dekho (object ke andar stored hoti hai).
Us class ki vtable par jao.
Jahan bhi area point karta hai, wahan jump karo.
Kyun yeh sahi behavior deta hai: kyunki object apna khud ka class pointer carry karta hai, chahe woh Shape-typed variable mein hold ho, step 1 Circle dhundh leta hai, isliye step 2 Circle.area dhundh leta hai. Declared type calculation mein kabhi aata hi nahi.
Recall Feynman: ek 12-saal ke bacche ko explain karo
Ek Toy jaanta hai sound() kaise banate hain. Ek Dog toy aur ek Cat toy dono toys hain, lekin dog kehta hai "Woof" aur cat kehti hai "Meow". Jab tum kisi bhi toy se uski awaaz nikaalne ko kaho, har toy pehle se jaanta hai apna tarika — tumhe yaad rakhne ki zarurat nahi ki woh kaunsi type ka hai. Method overriding bas har cheez ko allow karta hai ki woh ek hi sawaal ka apne sahi tarike se jawab de, automatically.
Ek subclass apni khud ki implementation deta hai ek aisi method ki jo already uske superclass mein defined hai, same name, parameters, aur compatible return type use karke.
Overriding vs overloading — kya differ karta hai?
Overriding = same signature, runtime par object type se resolve hota hai. Overloading = different parameters, compile time par argument types se resolve hota hai.
KAUNSA type decide karta hai ki kaunsa overridden method run hoga?
Object ka runtime (actual) type, variable ka declared/static type nahi — yahi dynamic dispatch hai.
Overriding mein vtable ka kya role hai?
Ek per-class table jo method name → code address map karti hai; child parent ki table copy karta hai phir overridden entries overwrite karta hai, taaki dispatch child ka version dhundh sake.
Overriding Open/Closed Principle ko kyun support karta hai?
Naya behavior ek naya subclass likh kar add hota hai (extension), existing type-checking if/else code edit karne ke bajaye (modification).
Kya tum overriding mein access narrow kar sakte ho?
Nahi — tum access widen kar sakte ho aur ek subtype return kar sakte ho (covariant return), lekin access narrow karna ya broader checked exceptions add karna substitutability (Liskov) todta hai.
Kya static methods override hote hain?
Nahi — woh hide hote hain (compile time par declared type se resolve hote hain); sirf instance methods override hote hain.
Override mein super() kya karta hai?
Parent ka method ka version call karta hai, child ko fully replace karne ki bajaye behavior extend karne deta hai.