Overloading = same name, different parameters, chosen at compile time. Overriding = same signature in a subclass, chosen at runtime.
Side by side
| Overloading | Overriding | |
|---|---|---|
| Where | Same class (or inherited) | Subclass redefines a superclass/interface method |
| Signature | Same name, different parameter list | Same name and same parameters |
| Return type | Anything | Same or a subtype (covariant) |
| Access | Anything | Same or wider |
| Checked exceptions | Anything | Same, narrower or none — never new/broader |
| Resolved | Compile time (static binding) | Runtime (dynamic dispatch) |
static / private / final | Can be overloaded | Cannot be overridden |
| Polymorphism kind | Compile-time | Runtime |
Overloading
public class Main {
static String show(int x) { return "int " + x; }
static String show(long x) { return "long " + x; }
static String show(double x) { return "double " + x; }
static String show(Integer x) { return "Integer " + x; }
static String show(Object x) { return "Object " + x; }
static String show(int... xs) { return "varargs " + xs.length; }
public static void main(String[] args) {
byte b = 5;
System.out.println(show(7)); // exact match
System.out.println(show(b)); // widening byte → int beats boxing
System.out.println(show(7L));
System.out.println(show(7.0f)); // float → double
System.out.println(show("hi")); // String → Object
System.out.println(show()); // only varargs fits
}
}int 7
int 5
long 7
double 7.0
Object hi
varargs 0Overriding with @Override
public class Main {
public static void main(String[] args) {
Shape s = new Circle(2); // reference type Shape, object Circle
System.out.println(s.name()); // runtime: Circle.name()
Circle copy = new Circle(2).copy(); // covariant return: no cast needed
System.out.printf("%.2f%n", copy.area());
}
}
class Shape {
protected String name() { return "shape"; }
Shape copy() { return new Shape(); }
double area() { return 0; }
}
class Circle extends Shape {
private final double r;
Circle(double r) { this.r = r; }
@Override public String name() { return "circle"; } // protected → public: widening OK
@Override Circle copy() { return new Circle(r); } // covariant return type
@Override double area() { return Math.PI * r * r; }
}circle
12.57class Point {
int x;
@Override
public boolean equals(Point other) { return other.x == x; } // wrong parameter type
}Main.java:3: error: method does not override or implement a method from a supertype
@Override
^Rules the compiler enforces
import java.io.IOException;
class Parent {
public void run() { }
void load() throws IOException { }
}
class Child extends Parent {
@Override protected void run() { } // narrowing public → protected
}Main.java:9: error: run() in Child cannot override run() in Parent
@Override protected void run() { } // narrowing public → protected
^
attempting to assign weaker access privileges; was publicAn override may throw fewer or narrower checked exceptions (
FileNotFoundExceptioninstead ofIOException), or none; unchecked exceptions are unrestricted.finalmethods can't be overridden;privatemethods aren't inherited, so a same-named subclass method is just a new method.Call the parent version with
super.method().
Static methods are hidden, not overridden
public class Main {
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.stat()); // static: chosen by reference type
System.out.println(p.inst()); // instance: chosen by object type
System.out.println(p.label); // fields are hidden too
System.out.println(((Child) p).label);
}
}
class Parent {
String label = "parent-field";
static String stat() { return "Parent.stat"; }
String inst() { return "Parent.inst"; }
}
class Child extends Parent {
String label = "child-field";
static String stat() { return "Child.stat"; }
@Override String inst() { return "Child.inst"; }
}Parent.stat
Child.inst
parent-field
child-fieldCan we overload main?
Can we override a static or private method?
Can two overloads differ only by return type?
What is a covariant return type?