Difficulty: Medium
Correct Answer: The call to an overridden instance method is resolved at runtime based on the actual object type referenced, not the reference variable type
Explanation:
Introduction / Context:
Runtime polymorphism through method overriding is one of the most important ideas in Java object oriented programming. It allows a superclass reference to point to objects of different subclasses and still call the correct overridden method implementation at runtime. This question checks whether you understand how Java decides which version of an overridden method to execute when there is inheritance and upcasting involved.
Given Data / Assumptions:
Concept / Approach:
Polymorphism literally means many forms. In Java, overriding based polymorphism refers to the ability of a single call expression to take different concrete forms depending on the object it is applied to. Java uses dynamic binding for non static, non final, non private instance methods. The key rule is that the compiler checks method existence and visibility using the reference type, but the Java Virtual Machine chooses the actual method body at runtime based on the real object type sitting in memory. This is what enables frameworks and libraries to work with abstract types while executing specific subclass behavior.
Step-by-Step Solution:
Step 1: Consider a superclass Animal with a method speak() and subclasses Dog and Cat that override speak().
Step 2: Write code like Animal a = new Dog(); and later call a.speak(). The reference variable a has type Animal but holds a Dog object.
Step 3: At compile time, the compiler only checks that Animal has a speak() method with the appropriate signature. This is a static type check.
Step 4: At runtime, the virtual machine inspects the actual object type stored in a, which is Dog, and dispatches the call to Dog.speak().
Step 5: If a were pointing to a Cat object, the same call a.speak() would invoke Cat.speak() instead. This ability to choose the method body at runtime is runtime polymorphism.
Step 6: The decision is therefore driven by the real object type, not only by the reference variable type.
Verification / Alternative check:
You can verify this behavior with a small Java program that prints different messages from overridden methods. Change only the concrete object assigned to the same reference variable and observe that the printed output changes even though the call site remains identical. This experiment clearly demonstrates that method calls to overridden instance methods are dynamically dispatched at runtime, which matches the definition of runtime polymorphism through method overriding.
Why Other Options Are Wrong:
Option B is wrong because instance method calls are not always resolved at compile time; only overloaded methods and some static or private methods are bound statically. Option C confuses polymorphism with constructor overloading, which is actually compile time polymorphism and a different concept. Option D misrepresents polymorphism by correctly mentioning multiple interfaces but then incorrectly claiming that method calls are always static, which contradicts dynamic dispatch rules.
Common Pitfalls:
Common mistakes include confusing method overloading with overriding, and assuming that the reference variable type controls which overridden method runs. Another frequent confusion in interviews is mixing the terms dynamic binding, late binding, overriding, and runtime polymorphism without grasping that they describe the same underlying mechanism. Remember that only instance methods that are overridden participate in runtime polymorphism; fields, static methods, and constructors do not.
Final Answer:
Runtime polymorphism through method overriding in Java means that the call to an overridden instance method is resolved at runtime based on the actual object type referenced, not the reference variable type.
Discussion & Comments