We don't "magically" get the right method. Let's build the mechanism.
Each class keeps a hidden method table (a "vtable"): a map from method name → code address.
vtable(C)={m↦most-derived definition of m visible in C}
Shape's table: area → Shape.area (maybe abstract/empty).
Circle's table starts as a copy of Shape's, then overwritesarea → Circle.area.
When you call obj.area():
Look at obj's actual class (stored inside the object).
Go to that class's vtable.
Jump to whatever address area points to.
Why this gives correct behavior: because the object carries its own class pointer, even when held in a Shape-typed variable, step 1 finds Circle, so step 2 finds Circle.area. The declared type never enters the calculation.
A Toy knows how to make a sound(). A Dog toy and a Cat toy are both toys, but a dog says "Woof" and a cat says "Meow". When you ask any toy to make its sound, each toy already knows its own way — you don't have to remember which kind it is. Method overriding is just letting each kind of thing answer the same question in its own correct way, automatically.
A subclass providing its own implementation of a method already defined in its superclass, using the same name, parameters, and compatible return type.
Overriding vs overloading — what differs?
Overriding = same signature, resolved at runtime by object type. Overloading = different parameters, resolved at compile time by argument types.
Which type decides WHICH overridden method runs?
The runtime (actual) type of the object, not the declared/static type of the variable — this is dynamic dispatch.
What is a vtable's role in overriding?
A per-class table mapping method name → code address; a child copies the parent's table then overwrites overridden entries, so dispatch finds the child's version.
Why does overriding support the Open/Closed Principle?
New behavior is added by writing a new subclass (extension) instead of editing existing type-checking if/else code (modification).
Can you narrow access when overriding?
No — you may widen access and return a subtype (covariant return), but narrowing access or adding broader checked exceptions breaks substitutability (Liskov).
Are static methods overridden?
No — they are hidden (resolved by declared type at compile time); only instance methods are overridden.
What does super() do in an override?
Calls the parent's version of the method, letting the child extend rather than fully replace the behavior.
Method overriding ka matlab simple hai: parent class ne ek method ka naam aur shape (signature) decide kiya, aur child class us same method ko apne tareeke se dobara likh deti hai. Jaise Shape ke paas area() hai, lekin Circle aur Rectangle dono area alag formula se nikaalte hain. Jab aap shape.area() call karte ho, to computer dekhta hai ki asli object kaun sa hai — variable ka declared type nahi, balki real object — aur usi ka version chalata hai. Isko hum dynamic dispatch bolte hain.
Yeh kaam kaise hota hai? Har class ke paas ek chhoti si table hoti hai (vtable) jisme likha hota hai "area ke liye yeh code chalao". Child class parent ki table copy karti hai, phir override kiye gaye method ki entry overwrite kar deti hai. Object apne andar apni class ka pointer rakhta hai, isliye Shape s = Circle likho tab bhi Circle.area hi chalega. Yeh hi reason hai ki declared type sirf compile-time pe check karta hai ki call allowed hai ya nahi, run karne wala version real object decide karta hai.
Iska fayda kya? Aapko lambe if shape is circle ... elif rectangle ... ladders nahi likhne padte. Naya shape add karna hai? Bas nayi class bana do, purana code chhedne ki zaroorat nahi — yeh Open/Closed Principle hai. Bas dhyan rakho: override mein signature same hona chahiye (warna woh overloading ban jaata hai), access tight mat karo (Liskov rule), aur static methods override nahi hote — woh sirf hide hote hain. Yaad rakhne ke liye: SORD — Same signature, Object decides, Runtime dispatch, DRY (if/else hatao).