Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Learn › Java › Classes and objects

Polymorphism and method selection

Who decides which method runs, and when?

The declared type of a variable and the type of the object that it actually holds can be different. An overridden method is chosen at run time by looking at the actual object, but overloading, static methods, and fields are decided at compile time from the declared type alone.

Checked against real execution · Every combination was compiled and run on JDK 21 and checked against the result

Concepts in this lab

Polymorphism
This is the property that calling the same method through a reference of the same type runs different behavior depending on the kind of the actual object. A variable of a supertype (an interface or a superclass) can hold objects of several subtypes, and which implementation runs is decided at run time (dynamic method lookup). It lets you add a new implementation without changing the calling code.
Overriding
This means that a subclass redefines a method of its superclass (or of an interface) with the same signature. At run time, the method that matches the type of the actual object is called, and this is how polymorphism is implemented. The access level cannot be made narrower, and static, private, and final methods cannot be overridden.
Overloading
This means defining several methods with the same name but with a different number or different types of parameters. Which method is called is decided at compile time from the types of the arguments. Methods that differ only in return type are not overloaded; that is a compile-time error.
static
This keyword marks a member as belonging to the class, not to an instance. A static field exists only once per class and is shared by all instances, and a static method is called without creating an object. A static field whose value changes is effectively a global variable, so it easily causes problems when several threads access it at the same time.
Inheritance
This means defining a new class (the subclass) that receives the fields and methods of an existing class (the superclass). It reuses common code, and the subclass adds or overrides only the parts it needs. A Java class supports single inheritance only, and a change to the superclass affects every subclass, so it is best used only when there is a clear "is-a" relationship.

Try these

Running with the default settings

  1. Compile time: Animal a = new Dog(). The declared type of the variable a is Animal, and when the code runs, an object of class Dog is created on the heap. The two are different.
  2. Compile time: The compiler checks only whether the declared type Animal has sound(). It does not decide which class's sound() will run, and it leaves only the instruction "call sound()".
  3. Run time: The JVM checks the class of the actual object that a refers to (Dog), and it finds and runs the sound() of that class (dynamic method lookup).

Result of this run

Code

class Animal {
    String name = "animal";
    void sound()       { System.out.println("Animal.sound"); }
    static void info() { System.out.println("Animal.info"); }
}
class Dog extends Animal {
    String name = "dog";                // a field with the same name
    @Override
    void sound()       { System.out.println("Dog.sound"); }
    static void info() { System.out.println("Dog.info"); }
}
class Printer {
    void print(Animal x) { System.out.println("print(Animal)"); }
    void print(Dog x)    { System.out.println("print(Dog)"); }
}

Animal a = new Dog();
a.sound();

Assumptions of this model

The output of every combination was checked against the result of actually compiling and running the same code on JDK 21 on this PC. Calling a static method through a variable, as in a.info(), is allowed by the syntax but is not a recommended practice, and it is included here to show that the call is decided by the declared type.

Previous lab: Inheritance and overriding · Next lab: Interfaces and abstract classes

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these