Method Overloading vs Overriding
Overloading and overriding sound alike and both reuse a method name, so they're easy to mix up. They are actually opposites in almost every way. Overloading is several methods with the same name and different parameters, chosen by the compiler. Overriding is one method replaced in a subclass with the same parameters, chosen by the JVM at runtime. This lesson puts them side by side, then shows a real bug caused by confusing them.
Side by Side
| Overloading | Overriding | |
|---|---|---|
| What it is | Same name, different parameter lists | Same name, same parameter list, in a subclass |
| Where | Usually in one class (or inherited into it) | Parent and child classes |
| Decided by | The compiler, from declared argument types | The JVM, from the object's actual class |
| Polymorphism | Compile-time (static) | Runtime (dynamic) |
| Return type | Can be anything | Same, or a subtype |
| Access modifier | Any | Same or wider |
| Checked exceptions | Any | None, same or narrower |
static methods | Can be overloaded | Can't be overridden (they're hidden) |
private and final methods | Can be overloaded | Can't be overridden |
| Annotation | None | @Override |
Both in One Program
public class Both {
static class Printer {
void print(String s) { System.out.println("Printer: " + s); }
void print(int n) { System.out.println("Printer number: " + n); }
}
static class ColorPrinter extends Printer {
@Override
void print(String s) { System.out.println("Color: " + s); }
}
public static void main(String[] args) {
Printer p = new ColorPrinter();
p.print("Navika");
p.print(42);
}
}Color: Navika
Printer number: 42How it works
print(String)andprint(int)inPrinterare overloads. Forp.print(42), the compiler picksprint(int)from the argument type.ColorPrinteroverrides onlyprint(String). Forp.print("Navika"), the compiler picksprint(String), then at runtime the JVM sees aColorPrinterobject and runs its version.print(int)isn't overridden, so the inheritedPrinterversion runs.
So both mechanisms work together in two steps: the compiler chooses the signature, then the JVM chooses the implementation of that signature.
The equals Trap
This class tries to override equals but actually overloads it:
public class Trap {
static class Account {
String id;
Account(String id) { this.id = id; }
public boolean equals(Account other) {
return id.equals(other.id);
}
}
public static void main(String[] args) {
Account a = new Account("A-101");
Account b = new Account("A-101");
Object o = b;
System.out.println(a.equals(b));
System.out.println(a.equals(o));
}
}true
falseHow it works
Objectdeclaresequals(Object). The class declaresequals(Account): a different parameter type, so it's an overload.Accountnow has twoequalsmethods.a.equals(b): the argument's declared type isAccount, so the compiler picks the new method, which compares ids:true.a.equals(o): the declared type isObject, so the compiler picks the inheritedObject.equals, which compares references:false.- Collections such as
HashSetandArrayList.containsalways callequals(Object), so they'd never use your method.
Common Mistakes
Calling an overload "overriding" in an interview. The parameter list is the deciding question: different means overloading.
Expecting overloads to be chosen by the runtime object. They're chosen by declared types at compile time.
Overloading methods inherited from Object by accident. equals(Account) and compareTo with the wrong type are classic examples.
Interview Corner
What is the difference between method overloading and method overriding?
Overloading is defining methods with the same name but different parameter lists, usually in the same class; the compiler picks one from the declared argument types, so it's compile-time polymorphism, and return types, access and exceptions can differ freely. Overriding is redefining an inherited instance method with the same signature in a subclass; the JVM picks the version from the object's actual class at runtime, and the override must keep a compatible return type, equal or wider access, and no broader checked exceptions. Static, private and final methods can be overloaded but not overridden.
Can we overload and override the main method?
main can be overloaded: other methods named main with different parameters are allowed, but the JVM starts the program only from the standard main signature. A static main can't be overridden; a subclass's static main only hides it.
Practice
- Easy: In a
Calculatorclass, overloadaddfor two and threeints. InScientificCalculator, override the two-argument version to print a log line before adding. - Harder: Fix the
Trapclass so both lines printtrue, using@Overrideand a parameter of typeObject.
Key Takeaways
Was this tutorial helpful?