Polymorphism

Polymorphism means "many forms". In Java it means one reference variable, parameter, or return type can refer to objects of different concrete classes, and the right code runs based on the actual object type at runtime.

Runtime polymorphism

public class Animal {
    public String sound() { return "..."; }
}
public class Dog extends Animal {
    @Override public String sound() { return "Woof"; }
}
public class Cat extends Animal {
    @Override public String sound() { return "Meow"; }
}

Animal a = new Dog();
System.out.println(a.sound());  // "Woof" — runtime dispatch picks Dog's method

a = new Cat();
System.out.println(a.sound());  // "Meow"

Interface-based polymorphism

List<String> list = new ArrayList<>();  // or LinkedList, CopyOnWriteArrayList...
list.add("hi");
// Callers don't know or care which List implementation they got.

Compile-time polymorphism (overloading)

void print(int n)    { System.out.println(n); }
void print(String s) { System.out.println(s); }
print(42);     // int overload
print("hi");   // String overload

The compiler picks the overload at compile time based on argument types.

See the full polymorphism guide.