| Claim | Verdict |
|---|
| Overloading and overriding are the same | False. One class versus two. |
| Overloading picks by argument values | False. By declared types. |
| Overriding uses the reference type | False. It uses the actual object. |
| Static methods are overridden | False. They are hidden, not overridden. |
| Fields are overridden polymorphically | False. They bind to the reference. |
| Overriding requires an interface | False. Any superclass works. |
| Overloading can fail at runtime | False. It fails at compile time. |
| Downcasting is needed to get the override | False. The JVM does it for you. |
Frequently Asked Questions
What is the real difference between static and dynamic polymorphism?
Static polymorphism is overloading, where the compiler chooses a method from the declared types of the arguments, and the decision is final once compiled. Dynamic polymorphism is overriding, where the JVM chooses the implementation from the actual object type when the call executes. The practical difference is how they fail: an unresolvable overload is a compile error, whereas an unwanted override is silently wrong behaviour.
Why does a call pick Object rather than Integer?
Because method resolution runs in phases, and widening beats boxing. Passing a primitive int cannot become an Integer without boxing, so widening to Object is the applicable match found in the earlier phase. Passing an already boxed Integer can match directly, so the Integer overload wins for that call.
Does overriding work with static methods?
No. A static method is bound at compile time by the reference type and is hidden rather than overridden. The same is true of private methods, which a subclass cannot see, and final methods, which forbid it outright. Only instance methods participate in dynamic dispatch.
Why does a field not behave polymorphically?
Because field access is resolved at compile time from the reference type, with no runtime lookup involved. A subclass field with the same name hides the parent one instead of replacing it, leaving two separate variables in the object. Methods dispatch on the object; fields bind to the declaration.
How do I avoid instanceof checks over a collection?
Declare the loop variable at the supertype and call a method declared there. Each object then runs its own override without any type test, and adding a subtype later needs no change to the loop. That is the main practical benefit of runtime polymorphism, and it is why the pattern is preferred over type branching.
Should I declare variables at the supertype or the concrete type?
Declare parameters and locals at the supertype and construct at the concrete type. A variable typed as the concrete class restricts which methods are callable and gains nothing, whereas a supertype-typed variable accepts any implementation and still dispatches to the right override at runtime.
What happens when two interfaces supply the same default?
The compiler reports a conflict, because it will not choose between them. The implementing class must override the method and may call either parent explicitly with a qualified super call. This is the diamond ambiguity, which is precisely why classes may extend only one parent while interfaces may multiply inherit.
Is operator overloading part of this?
No, and its absence is worth noting. Java does not let you define operator behaviour, so plus on two objects means concatenation for strings and addition for numbers, with no polymorphic dispatch. Overloading in Java always means method overloading chosen by the compiler.