Kyūkei Master Hub
SCS2108 | Phase Study Card
👁️ -- opens | 0%

Phase 10B: Demystifying Method Overriding vs. Overloading

Overriding and Overloading are two forms of Polymorphism that students frequently confuse in exam code traces. This deep dive breaks down the rules, compiler traps, and memory dispatch mechanics once and for all.

1. The Mental Models: Never Confuse Them Again

☕ Overloading Analogy: Multi-Tool Coffee Machine (Compile-Time)

Imagine a coffee machine with buttons labeled brew(), brew(Sugar), and brew(Sugar, Milk). They are all in the SAME machine. They share the SAME action name (brew), but take DIFFERENT inputs. The compiler knows at compile time exactly which button you pressed based on the ingredients you handed it!

📱 Overriding Analogy: Smartphone OS Update (Runtime)

Imagine your base phone (Parent class) has a method displayNotification() that shows a plain white popup. When you upgrade to iOS 18 (Subclass), it replaces / overrides displayNotification() with a slick Dynamic Island widget. The signature is EXACTLY the same, but the subclass provides a custom, upgraded implementation that replaces the parent's logic at runtime!

2. The 6 Immutable Rules Matrix (Examiner Trap Cheat Sheet)

Examiners love testing boundary cases where code fails to compile due to subtle rule violations. Memorize this comparison matrix:

Rule Category Method Overloading (Compile-Time) Method Overriding (Runtime)
Where It Occurs Within the same class (or inherited methods). Between Parent Class & Child Subclass (or Interface & Implementation).
Method Name MUST be identical. MUST be identical.
Parameter List MUST be different (count, order, or data types). MUST be exact same count, types, and order.
Return Type Can be anything (different or same). Cannot overload on return type alone! MUST be same or a Covariant Subtype (e.g. parent returns Animal, child returns Dog).
Access Modifiers Can be changed freely (private, public, etc.). CANNOT reduce visibility! (e.g., parent public cannot become child protected or private).
Exception Declarations Can throw any checked or unchecked exceptions. Child CANNOT declare broader or new checked exceptions than declared by parent!
Static / Final / Private Methods Static, final, and private methods CAN be overloaded. Static methods undergo Method Hiding (not overriding!). Final & Private methods CANNOT be overridden.
⚠️ Examiner Trap #1: Overloading on Return Type Alone

The code below causes a COMPILE-TIME ERROR:

public class Calculator { public int add(int a, int b) { return a + b; } public double add(int a, int b) { return a + b; } // ❌ COMPILE ERROR! Signature add(int, int) is duplicate! }

The compiler determines overloading strictly by the Method Signature (Method Name + Parameter List). It ignores return type when matching!

3. Dynamic Method Dispatch vs. Static Binding (The Code Trace Engine)

In Part 2.1 exams, you will get polymorphic assignment questions like: Parent p = new Child();

How does Java decide which version of a method or field to invoke? Here is the golden rule:

🌟 The Polymorphism Memory Formula
  • Instance Methods (Overridden): Bound at RUNTIME based on the Actual Object Type on Heap (the right side of new).
  • Instance Variables (Fields): Bound at COMPILE TIME based on the Reference Type (the left side of =).
  • Static Methods: Bound at COMPILE TIME based on the Reference Type (Static Method Hiding).

Code Anatomy Trace Example:

class Parent { int x = 10; static void printStatic() { System.out.println("Parent Static"); } void printInstance() { System.out.println("Parent Instance (" + x + ")"); } } class Child extends Parent { int x = 20; // Field hiding! static void printStatic() { System.out.println("Child Static"); } // Method hiding! @Override void printInstance() { System.out.println("Child Instance (" + x + ")"); } // Method overriding! } public class TestPolymorphism { public static void main(String[] args) { Parent obj = new Child(); // Reference: Parent | Heap Object: Child System.out.println(obj.x); // 1️⃣ Field -> Uses Reference Type (Parent) -> Prints 10! obj.printStatic(); // 2️⃣ Static Method -> Uses Reference Type (Parent) -> Prints Parent Static! obj.printInstance(); // 3️⃣ Instance Method -> Uses Heap Type (Child) -> Prints Child Instance (20)! } }

4. Overloading Resolution Hierarchy (Primitive Widening & Autoboxing)

When you call an overloaded method like calc(5), Java resolves the best match in this strict sequence:

  1. Exact Type Match (e.g. calc(int))
  2. Implicit Primitive Widening (e.g. int widens to long -> float -> double)
  3. Autoboxing / Unboxing (e.g. int boxes to Integer)
  4. Varargs (e.g. calc(int... args) - lowest priority!)
public class ResolutionDemo { static void test(long x) { System.out.println("Widened to long"); } static void test(Integer x) { System.out.println("Autoboxed to Integer"); } static void test(int... x) { System.out.println("Varargs int..."); } public static void main(String[] args) { int val = 5; test(val); // Prints: "Widened to long" (Primitive widening beats Autoboxing!) } }

5. Interactive Self-Test Exam Drills

Q1: Overriding Access Modifier Rules

Parent class has: protected void compute() {}
Child class attempts: void compute() {} (package-private).
Does this code compile? Explain why or why not.

COMPILE ERROR

Reasoning: In Java overriding, a subclass method cannot reduce the visibility of the parent method. protected is more accessible than package-private (default). To override correctly, the child method must be marked either protected or public.

Q2: Checked Exception Overriding Rule

Parent has: public void readData() throws IOException {}
Child has: @Override public void readData() throws Exception {}
Does this compile? Explain the rule.

COMPILE ERROR

Reasoning: Exception is the superclass of IOException (broader exception). An overridden method in a subclass CANNOT declare broader checked exceptions than the superclass method! It can only throw the same exception, a subtype exception (e.g. FileNotFoundException), or no checked exception at all.

Q3: Covariant Return Type Verification

Parent: public Animal getPet() { return new Animal(); }
Child: @Override public Dog getPet() { return new Dog(); } (where Dog extends Animal).
Is this valid Java code?

VALID (COMPILES CLEANLY)

Reasoning: Since Java 5, Java supports Covariant Return Types. Since Dog is a subtype of Animal, returning a more specific subtype in the overriding method is 100% legal and recommended.