What is the difference between overloading and overriding?
Overloading and overriding are different mechanisms that are often confused because both involve the same method name.
Overloading is compile-time polymorphism: several methods share a name but differ in their parameter list. The compiler picks one from the static types of the arguments.
void print(int x) { }
void print(String s) { }
Overriding is runtime polymorphism: a subclass provides its own version of a method inherited from the superclass with the same signature. The runtime picks the implementation from the actual object type.
class A { void hi() { System.out.println("A"); } }
class B extends A { @Override void hi() { System.out.println("B"); } }
A a = new B(); a.hi(); // B
Overloading cannot be decided by return type alone, and overriding must not reduce visibility or throw broader checked exceptions. Overloading is resolved on the declared type; overriding on the runtime type.