← Back to CS Fundamentals

Overriding vs Overloading

CS FundamentalsEntry

The Question

What is the difference between method overriding and method overloading?

What a Strong Answer Covers

  • overriding = subclass replaces parent
  • "Python has no true overloading
  • "last definition wins

Senior-Level Answer

Method overriding and method overloading are both forms of polymorphism but operate at different points in the execution lifecycle and serve distinct purposes.

**Method overriding** occurs in inheritance hierarchies. A subclass provides its own implementation of a method that is already defined in a parent class, using the same name, same parameters, and same return type. At runtime, when the method is called on an object, the actual runtime type of the object determines which implementation executes—this is dynamic dispatch (or late binding). Overriding is the mechanism behind polymorphism: you can write code against a base class interface and have subclass behavior execute transparently.

In Python, overriding is implicit—just define a method with the same name in a subclass. In Java/C#, methods are overridable by default (Java) or must be marked `virtual`/`override`. The `super()` call allows invoking the parent's implementation within the override.

**Method overloading** allows defining multiple methods with the same name but different parameter signatures (number or types of parameters). The compiler (in statically typed languages like Java) selects the correct method to call at compile time based on the argument types—this is static dispatch (or early binding). Overloading is a compile-time feature.

Python does not natively support method overloading in the traditional sense—the last definition of a function name wins. Overloading is simulated using default arguments, `*args`/`**kwargs`, or `functools.singledispatch` for type-based dispatch.

The key distinctions: overriding is runtime, inheritance-based, and achieves subtype polymorphism. Overloading is compile-time (or statically dispatched), signature-based, and achieves ad-hoc polymorphism. Overriding requires a parent-child class relationship; overloading does not.

A common interview clarification: Python's `__dunder__` methods (like `__add__`, `__str__`) are a form of operator overloading—different from overriding in that they're invoked by operators/builtins rather than direct calls.

Key Differences

AspectMethod OverridingMethod Overloading
When resolvedRuntime (dynamic dispatch)Compile time (static dispatch)
Requires inheritanceYes (subclass of parent)No
Parameter signatureMust match parentMust differ (types or count)
Python supportYes (native)No (simulated with defaults/*args)
Type of polymorphismSubtype polymorphismAd-hoc polymorphism
Key mechanismVirtual method table / MROCompiler signature resolution

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Correctly defines overriding as runtime/subclass replacement and overloading as same-name/different-signature, explains dynamic vs. static dispatch, notes Python doesn't support true overloading.

3/3 — Strong Answer

Makes compile-time vs. runtime distinction explicit, explains dynamic dispatch mechanism for overriding, explains how Python simulates overloading, mentions super() and when to use it, and connects overriding to the Liskov Substitution Principle.

Common Mistakes

  • Confusing the two terms — a surprisingly common error under pressure
  • Saying Python supports overloading — it doesn't natively; the last definition wins
  • Missing the dispatch timing difference — overriding is runtime, overloading is compile-time
  • Not explaining when you'd actually use each, which is what interviewers want

Follow-Up Questions

  • How does Python simulate method overloading? — Default arguments handle optional params. *args/**kwargs handle variable arity. functools.singledispatch enables type-based dispatch. The last definition of a name always wins otherwise.
  • What is the Liskov Substitution Principle and how does it relate to overriding? — LSP states a subclass should be substitutable for its parent without breaking behavior. Overrides should strengthen postconditions or weaken preconditions, never the reverse.
  • When would you call super() inside an overriding method? — When you want to extend (not fully replace) the parent behavior — e.g., calling parent.__init__() before adding subclass-specific init logic, or in cooperative multiple inheritance.
  • What's the difference between overriding and shadowing? — Overriding replaces a method via inheritance with the correct signature. Shadowing hides a name in an outer scope with a new binding in an inner scope — not related to inheritance.

Related Questions

  • Process vs Thread
  • Race Condition
  • Deadlock — 4 Conditions, Prevention
  • Thread Safety — Is dict Thread Safe?
  • HashMap Internals

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout