Skip to content
UniCircle
MediumConceptualPolymorphism

How does runtime polymorphism work in Java?

Question JAVA-POL-014

Given Animal a = new Dog(); a.speak();, which speak() runs and why? Which members are not chosen at runtime?

Show the explanation

Dog.speak() runs. The compiler checks that speak() exists on the declared type Animal; at runtime the JVM looks at the actual object (Dog) and calls its override. This is dynamic dispatch.

Java
class Animal { String name = "animal"; String speak() { return "..."; } static String kind() { return "Animal"; } }
class Dog extends Animal { String name = "dog"; @Override String speak() { return "Woof"; } static String kind() { return "Dog"; } }

Animal a = new Dog();
a.speak();   // "Woof"   - instance method: chosen by the object
a.name;      // "animal" - fields are not polymorphic: chosen by the declared type
a.kind();    // "Animal" - static methods are hidden, not overridden

Only non-static, non-private, non-final instance methods are dispatched dynamically. Fields, static methods and private methods are resolved from the declared type at compile time. Overloading is also decided at compile time, from the declared argument types. (For overloading vs overriding in general, see OOP-POL-001.)

Original UniCircle question. Last reviewed 22 Oct 2026.