Java Polymorphism
Polymorphism means 'many forms' — the ability for the same method call to behave differently depending on the object it's called on. Java achieves this through method overriding (runtime polymorphism) and method overloading (compile-time polymorphism).
A superclass reference can point to a subclass object, and calling an overridden method invokes the subclass's version — this is central to flexible, extensible OOP designs.
class Sub extends Super {
@Override
void method() { }
}Method overriding
A subclass provides its own implementation of a method already defined in its superclass, using the same signature and the @Override annotation.
Runtime polymorphism in action
When a superclass-typed variable holds a subclass object, calling an overridden method executes the subclass's version at runtime, not the superclass's.
class Animal {
void sound() { System.out.println("Some sound"); }
}
class Cat extends Animal {
@Override
void sound() { System.out.println("Meow"); }
}
public class Main {
public static void main(String[] args) {
Animal a = new Cat();
a.sound();
}
}MeowEven though a is typed as Animal, it holds a Cat object, so the overridden sound() runs.
Key points
- Polymorphism lets the same call behave differently per object type.
- Overriding is resolved at runtime based on the actual object type.
- Overloading is resolved at compile time based on arguments.
- @Override helps catch mistakes when overriding methods.
