Understanding the difference between method overloading and method overriding in Java is essential for mastering polymorphism in object-oriented programming. In this beginner-friendly guide, you’ll learn what each concept means, why we use them, the rules to remember, and how to write clear examples. We’ll also answer common questions students ask and show practical use cases you can apply in projects. If you’re just starting out, you can explore more beginner topics in our Java tutorials.
- Method Overloading: same method name in the same class with different parameter lists; chosen by the compiler at compile time.
- Method Overriding: same method signature in a subclass providing a new implementation; selected by the JVM at runtime based on the object’s actual type.
Method Overloading in Java (Compile-Time Polymorphism)
What is method overloading?
Method overloading in Java means having multiple methods with the same name in the same class, but with different parameter lists. This is an example of compile-time polymorphism because the Java compiler decides which method to call based on the argument types and the number of arguments at compile time.
Key rules for method overloading
- Same method name, different parameter list (type, number, or order).
- Return type is NOT part of the method signature. You cannot overload only by changing the return type.
- Throws clauses don’t affect overloading.
- Constructors can be overloaded (but not overridden).
- Overload resolution happens at compile time using the argument types available at the call site.
Simple example: Calculator with overloaded methods
class Calculator {
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
int add(int a, int b, int c) { return a + b + c; }
}
class="cd-keyword cd-access">public class OverloadingDemo {
class="cd-keyword cd-access">public static void main(String[] args) {
Calculator c = new Calculator();
System.out.println(c.add(2, 3)); // calls add(int, int)
System.out.println(c.add(2.5, 1.5)); // calls add(double, double)
System.out.println(c.add(1, 2, 3)); // calls add(int, int, int)
}
}5
4.0
6Constructor overloading example
class Student {
String name;
int age;
Student(String name) {
this(name, 0); // calls the other constructor
}
Student(String name, int age) {
this.name = name;
this.age = age;
}
class="cd-keyword cd-access">public String toString() {
return name + " (" + age + ")";
}
}
class="cd-keyword cd-access">public class ConstructorOverloadingDemo {
class="cd-keyword cd-access">public static void main(String[] args) {
Student s1 = new Student("Asha");
Student s2 = new Student("Ravi", 20);
System.out.println(s1);
System.out.println(s2);
}
}Asha (0)
Ravi (20)Method Overriding in Java (Runtime Polymorphism)
What is method overriding?
Method overriding in Java happens when a subclass provides its own implementation of a method that is already defined in its superclass (or interface). The overriding method must have the same name and the same parameter list (i.e., the same signature). This enables runtime polymorphism: the actual method that runs is chosen at runtime based on the object’s real type, not the reference type.
Key rules for method overriding
- Must have the same method signature as the superclass method.
- Use
@Overrideto catch mistakes at compile time. - Access level cannot be reduced (you can make it more visible, not less).
- Covariant return types are allowed (the overriding method can return a subtype of the original return type).
- For checked exceptions, the overriding method can declare the same or fewer (narrower) checked exceptions.
- Static methods are not overridden; they are hidden. Final and private instance methods cannot be overridden.
Simple example: Animal sounds
class Animal {
void speak() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
class="cd-annotation">@Override
void speak() {
System.out.println("Woof");
}
}
class Cat extends Animal {
class="cd-annotation">@Override
void speak() {
System.out.println("Meow");
}
}
class="cd-keyword cd-access">public class OverridingDemo {
class="cd-keyword cd-access">public static void main(String[] args) {
Animal a1 = new Dog(); // reference type Animal, object type Dog
Animal a2 = new Cat(); // reference type Animal, object type Cat
a1.speak(); // prints ___CDPHSTR3___ (runtime decision)
a2.speak(); // prints ___CDPHSTR4___
}
}Woof
MeowCovariant return types example
class Document {
Document duplicate() {
return new Document();
}
}
class Report extends Document {
class="cd-annotation">@Override
Report duplicate() { // covariant return: Report is a subclass of Document
return new Report();
}
}
class="cd-keyword cd-access">public class CovariantReturnDemo {
class="cd-keyword cd-access">public static void main(String[] args) {
Document d = new Report();
Document copy = d.duplicate();
System.out.println(copy.getClass().getSimpleName());
}
}ReportOverriding default methods from interfaces
Since Java 8, interfaces can have default methods. A class can inherit and use them, or override them just like any other instance method. If your class implements two interfaces that provide the same default method, you must resolve the conflict by overriding the method and optionally calling a specific interface’s default with InterfaceName.super.method().
interface Drawable {
default void draw() {
System.out.println("Drawing shape");
}
}
class Circle implements Drawable { }
class FancyCircle extends Circle {
class="cd-annotation">@Override
class="cd-keyword cd-access">public void draw() {
System.out.println("Drawing fancy circle");
}
}
class="cd-keyword cd-access">public class DefaultMethodDemo {
class="cd-keyword cd-access">public static void main(String[] args) {
Drawable d1 = new Circle();
Drawable d2 = new FancyCircle();
d1.draw(); // default method
d2.draw(); // overridden
}
}Drawing shape
Drawing fancy circleOverloading vs Overriding: Key Differences
Here is a clear comparison to help you remember the difference between method overloading and method overriding in Java:
| Aspect | Method Overloading | Method Overriding |
|---|---|---|
| Where it happens | Same class (or with inheritance but typical in the same class) | Between superclass and subclass (or interface and implementer) |
| Purpose | Provide multiple ways to call a method for convenience | Provide a new behavior for an inherited method |
| Binding time | Compile time (method chosen by the compiler) | Runtime (method chosen by the JVM using dynamic dispatch) |
| Signature | Must differ by parameter list | Must match the superclass method’s signature |
| Return type | Not part of signature (cannot overload by return type alone) | Can be covariant (subtype of original return type) |
| Access modifiers | No specific restriction | Cannot reduce visibility (e.g., public cannot become protected) |
| Exceptions | No effect on overloading | Checked exceptions must be same or narrower |
| Static/final/private | Can overload static, final, or private methods freely | Static methods are not overridden; final/private cannot be overridden |
| Constructors | Can be overloaded | Cannot be overridden |
| Polymorphism type | Compile-time polymorphism | Runtime polymorphism |
| Annotation | @Override not used |
Use @Override to avoid mistakes |
Real-world style examples
- Overloading example: A logging utility might have
log(String message),log(Exception e), andlog(String format, Object... args)to handle different inputs easily. - Overriding example: Payment processing: a base class
PaymentProcessor.process(Order)overridden byCreditCardProcessor,UpiProcessor, andWalletProcessorto implement provider-specific logic.
Common mistakes and best practices
- Thinking return type can overload a method: It cannot. The parameter list must change.
- Forgetting @Override: Without it, a typo can create an overload instead of an override. Always use
@Overridefor overrides. - Overloading pitfalls with autoboxing/varargs: Widening beats boxing, and boxing beats varargs. Be explicit to avoid confusion.
- Trying to override static/final/private methods: Static methods can be hidden (not overridden). Final and private methods cannot be overridden.
- Reducing method visibility when overriding: Not allowed. You may widen visibility (e.g., protected to public), but not reduce it.
- ✅ Same behavior, different inputs needed in one class? Overload with distinct parameter lists.
- ✅ Need specialized behavior for a subclass? Override with the same signature and use
@Override. - ✅ Prefer clarity: avoid ambiguous overloads with autoboxing/varargs; add explicit types.
- ❌ Don’t try to overload by only changing the return type.
- ❌ Don’t reduce visibility when overriding (e.g., public → protected).
- ❌ Don’t “override” static/final/private methods; static can only be hidden, final/private cannot be changed.
Autoboxing vs widening overloading pitfall
class OverloadPitfall {
void m(Integer x) { System.out.println("Integer"); }
void m(long x) { System.out.println("long"); }
class="cd-keyword cd-access">public static void main(String[] args) {
new OverloadPitfall().m(5); // int literal: chooses widening to long, not boxing to Integer
}
}longExamples of overloading and overriding in Java together
This small program shows both concepts at once: multiple print methods (overloading) and a subclass changing how one of them behaves (overriding).
class Printer {
void print(String s) { System.out.println("Text: " + s); }
void print(int n) { System.out.println("Number: " + n); }
void print(Object o) { System.out.println("Object: " + o); }
}
class ColorPrinter extends Printer {
class="cd-annotation">@Override
void print(String s) { System.out.println("Color text: " + s); }
}
class="cd-keyword cd-access">public class OverloadOverrideTogether {
class="cd-keyword cd-access">public static void main(String[] args) {
Printer p1 = new Printer();
Printer p2 = new ColorPrinter();
p1.print("Hello");
p1.print(10);
// Overriding at runtime
p2.print("Hello");
// Overloading chosen at compile time
p2.print(10);
// Overloading with reference type Object
Object obj = "Hi";
p2.print(obj);
}
}Text: Hello
Number: 10
Color text: Hello
Number: 10
Object: HiCompile time vs runtime polymorphism in Java
Method overloading is compile-time polymorphism: the compiler uses the declared types of arguments to pick the best-matching method signature. Method overriding is runtime polymorphism: the JVM uses the actual object type at runtime to dispatch the call. This is why an Animal reference can call Dog’s speak() when it points to a Dog object.
FAQ
What is the difference between method overloading and method overriding in Java?
Overloading uses the same method name in the same class with different parameter lists, and the compiler decides which to call. Overriding uses the same method signature in a subclass to replace the superclass behavior, and the JVM decides which implementation to run at runtime.
Which one is compile time and which is runtime in Java: overloading or overriding?
Overloading is compile-time polymorphism. Overriding is runtime polymorphism (dynamic dispatch).
Can we override a static method in Java?
No. Static methods are resolved at compile time and can only be hidden, not overridden. Final and private instance methods also cannot be overridden.
Why do we use method overloading and method overriding?
- Overloading: convenience and readability by providing multiple ways to call a method with different parameters.
- Overriding: specialization and flexibility by changing inherited behavior in subclasses.
How do you write simple examples of overloading and overriding in Java?
Overloading: write multiple add methods with different parameter types. Overriding: subclass Animal with Dog and override speak(). See the examples above for complete code and outputs.
Summary
If you remember just one line: overloading changes the parameter list (chosen at compile time), while overriding changes the implementation in a subclass (chosen at runtime). Use @Override, avoid relying on return type for overloading, and be cautious with autoboxing and varargs. These concepts unlock powerful patterns in object-oriented design and are the foundation for polymorphism in Java for beginners and beyond.
Sources / Further reading
- Oracle Java Tutorials: Overriding and Hiding Methods
- Oracle Java Tutorials: Default Methods
- Java Language Specification, Chapter 8: Classes (Overriding and Overloading)
- Java Language Specification, Chapter 15: Expressions (Method Invocation and Overload Resolution)
- Java Language Specification, Chapter 9: Interfaces
- Baeldung: Method Overloading and Overriding in Java


