Inheritance
Method Overriding
Master runtime dynamic binding, vtable lookups, signature rules, exception variance boundaries, and final/static constraints.
Interview: Core interview focus: dynamic binding, exception throwing constraints, covariance return rules, and the difference between overriding and hiding.
Method Overriding allows a subclass to provide a specific implementation of a method that is already declared in its superclass. This mechanism forms the foundation of Runtime Polymorphism (Dynamic Binding) in Java.
vtable & Dispatch
The JVM resolves overridden methods at runtime using Virtual Method Tables (vtables) containing pointers to resolved implementations.
Checked Exceptions
Subclasses can declare fewer or narrower checked exceptions, but cannot throw broader or new checked exceptions than the parent.
Overriding Rules
Requires identical signatures, non-narrowing access modifiers, and covariant return types. Private/final methods cannot be overridden.
Runtime Dynamic Method Dispatch (vtable)
Dynamic binding is how Java decides which method to run. At compile time, the compiler only verifies that the reference variable's type contains the declared method. At runtime, the JVM looks at the actual object on the heap:
- Every loaded class has a vtable (Virtual Method Table) in Metaspace containing entry points for all instance methods.
- When calling
animal.makeSound(), the JVM identifies the exact class of the heap object, indexes its vtable, and calls the resolved method implementation. - If the subclass does not override, the vtable inherits the parent class pointer. If it does, the pointer is updated to the subclass method.
Checked Exception Rules in Overriding
To preserve polymorphism, the compiler enforces strict bounds on exceptions:
- An overriding subclass method can throw fewer or narrower (more specific) checked exceptions. For example, if the parent method declares
throws IOException, the child can declarethrows FileNotFoundExceptionor omit the clause entirely. - An overriding subclass method cannot throw broader or new checked exceptions (e.g., throwing
Exceptionwhen parent throwsIOException). This prevents callers using a parent reference from receiving unhandled checked exceptions. - The subclass method can declare any unchecked exceptions (e.g.,
NullPointerException) without restriction.
Static Method Hiding
Static methods cannot be overridden. If a subclass declares a static method with the same signature as a superclass static method, it is called method hiding. The method executed depends on the compiler's reference type rather than the runtime object type, as static calls are bound at compile time.
Common Pitfalls
- Attempting to override static methods: Writing static methods in subclasses and expecting polymorphic runtime behavior, resulting in compile-time binding executing parent methods.
- Narrowing access permissions: Attempting to override a public parent method with protected or default access in the subclass, yielding a compiler error.
Best Practices
- Always Use the @Override Annotation: This enables the compiler to verify that your signature matches a parent method, catching typos and argument mismatches early.
- Keep Exception Declarations Narrow: Only throw specific exceptions that represent direct failure paths of the subclass logic.
Interview-Relevant Information
Q1: What are the overriding rules regarding access modifiers?
Answer: The subclass method must have access permissions that are the same as or wider than the parent method. For instance, a protected method can be overridden as protected or public, but not as default (package-private) or private.
Q2: Why can final and private methods not be overridden?
Answer: final methods explicitly forbid subclass customization for safety or security. private methods are not visible outside the declaring class, meaning they are not inherited, and a subclass declaring the same signature is simply creating a new independent method, not overriding.
Quick Checklist
Can you explain how the vtable is indexed at runtime, list the checked exception rules for subclass overrides, and explain the behavioral difference between static method hiding and instance overriding? If yes, you understand method overriding.
Use Cases
Customizing domain actions in base interface adapters (e.g., customizing toString() or equals() methods).
Implementing specialized operations in abstract processor engines (e.g., custom payment gateways).
Common Mistakes
Declaring new checked exceptions in overridden subclass methods, causing compile-time errors.
Confusing method overriding with overloading due to small signature changes (e.g., changing parameter type).