2.1.11OOP Fundamentals

Method overriding — when and why

1,954 words9 min readdifficulty · medium3 backlinks

WHAT it is

Contrast three look-alikes (steel-man these confusions early):

Concept Same name? Same params? Resolved when?
Overriding yes yes (same signature) runtime (object type)
Overloading yes different params compile time (arg types)
Shadowing/hiding yes (fields/static) compile time (declared type)

WHY it exists

Three reasons we override:

  1. Specialize — child does the job in a way that fits it (Circle.area).
  2. Extend — child does extra plus the parent's work (call super() then add).
  3. Fulfill a contract — an abstract/base method must be implemented by children.

HOW it works — derive dynamic dispatch from scratch

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)={mmost-derived definition of m visible in C}\text{vtable}(C) = \{\, m \mapsto \text{most-derived definition of } m \text{ visible in } C \,\}
  • Shape's table: area → Shape.area (maybe abstract/empty).
  • Circle's table starts as a copy of Shape's, then overwrites area → Circle.area.

When you call obj.area():

  1. Look at obj's actual class (stored inside the object).
  2. Go to that class's vtable.
  3. 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.

Figure — Method overriding — when and why

Worked examples


Common mistakes (Steel-man + fix)


The 80/20 of this topic


Recall Feynman: explain to a 12-year-old

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.


Active-recall flashcards

What is method overriding?
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.

Connections

  • Inheritance — overriding only happens along an inheritance chain.
  • Polymorphism — overriding is the engine of runtime polymorphism.
  • Method overloading — the compile-time look-alike to contrast against.
  • Abstract classes and interfaces — methods that must be overridden.
  • Liskov Substitution Principle — the rule overrides must respect.
  • Open-Closed Principle — the design payoff of overriding.
  • super keyword — extending a parent's behavior.

Concept Map

means

requires

resolved by

selects on

implemented via

copies then overwrites

lets step1 find

looked up using

enables

because it

contrasts, resolved compile time

contrasts, uses declared type

Method overriding

Subclass reimplements method

Same name and params

Dynamic dispatch

Runtime object type

Per-class vtable

Object class pointer

Open/Closed Principle

Kills if-else ladders

Overloading

Shadowing/hiding

Hinglish (regional understanding)

Intuition Hinglish mein samjho

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).

Go deeper — visual, from zero

Test yourself — OOP Fundamentals

Connections