Unit 3 · OOP Concepts

3.6.1Compile-time and run-time polymorphism

Polymorphism comes in two forms. The difference is when Java decides which method will run: while the code is being compiled, or while the program is running.

KindAlso calledHow achievedDecided
Compile-timeStatic bindingMethod overloadingBy the compiler, from the arguments
Run-timeDynamic bindingMethod overridingBy the JVM, from the actual object

Overloading was covered in 3.1.6; overriding in 3.5.4.

Compile-time polymorphism (overloading)

Java
void print(int x)    { System.out.println("int: " + x); }
void print(String s) { System.out.println("String: " + s); }

print(5);        // the compiler picks print(int)
print("Hello");  // the compiler picks print(String)

The compiler can see the argument types in the source code, so it fixes the choice before the program ever runs. Nothing about the choice can change at run time. It is called static binding because it is fixed.

Run-time polymorphism (overriding)

Java
Animal a;
if (userChoice == 1) a = new Dog();
else                 a = new Cat();
a.sound();       // Woof or Meow: only known while the program runs

Here the compiler cannot know which object a will refer to, because it depends on the user's choice. All the compiler checks is that Animal has a sound() method. When the line runs, the JVM looks at the actual object and calls its version. This is dynamic binding.

What is not polymorphic

Only instance methods that can be overridden use dynamic binding. These are always decided at compile time, from the variable's declared type:

Remember

  • Overloading: same name, different parameters, chosen by the compiler.
  • Overriding: same signature in a subclass, chosen by the JVM from the actual object.
  • The declared type decides what you may call; the actual object decides which overridden version runs.