Hiding Static Methods
Only instance methods in an object can be overridden. However, a static method in a subclass can hide a static method from the superclass. Hiding a static method is analogous to overriding an instance method except for one important aspect: Calls to static methods are bound at compile time as opposed to runtime for calls to overridden instance methods, and therefore do not exhibit polymorphic behavior exhibited by calls to overridden instance methods (p. 278).
When hiding a static method, the compiler will flag an error if the signatures are the same, but the other requirements regarding the return type, throws clause, and accessibility are not met. If the signatures are different, the method name is overloaded, not hidden.
A static method in the subclass can only hide a static method in the superclass. Analogous to an overridden instance method, a hidden superclass static method is not inherited. Analogous to accessing hidden static fields, a hidden static method in the superclass can always be invoked by using the superclass name or by using the keyword super in non-static code in the subclass declaration.
Example 5.2 illustrates invocation of static methods using references. Analogous to accessing fields, the static method invoked at (23), (24), and (25) is determined by the declared type of the reference. At (23), the declared reference type is TubeLight; therefore, the static method printLightType() at (10) in this class is invoked. At (24) and (25), the declared reference type is Light, and the hidden static method print-LightType() at (5) in that class is invoked. This is borne out by the output from the program.
In summary, a subclass can do any of the following:
- Access inherited members using their simple names
- Override a non-final instance method with the same signature as in the superclass
- Overload a static or instance method with the same name as in the superclass
- Hide a static non-final method with the same signature as in the superclass
- Hide a static or instance field with the same name as in the superclass
- Declare new members that are not in the superclass
- Declare constructors that can invoke constructors in the superclass implicitly, or use the super() construct with the appropriate arguments to invoke them explicitly (p. 209)
Table 5.1 provides a comparison between overriding, hiding, and overloading of methods.
Table 5.1 Overriding, Hiding, and Overloading of Methods
Comparison criteria | Overriding of instance methods/Hiding of static methods | Overloading of instance and static methods |
Method name | Must be the same. | Must be the same. |
Argument list | Must be the same. | Must be different. |
Return type | Can be the same type or a covariant type. | Can be different. |
throws clause | Can be restrictive about checked exceptions thrown. Must not throw new checked exceptions, but can include subclasses of exceptions thrown. | Can be different. |
Accessibility | Can make it less restrictive, but not more restrictive. | Can be different. |
final modifier | A final instance/static method cannot be overridden/hidden. Compile-time error if final instance/static method is defined in a subclass. | Can be overloaded in the same class or in a subclass. |
private modifier | A private instance/static method cannot be overridden/hidden. No compile-time error if private instance/static method is defined in a subclass. | Can be overloaded only in the same class. |
Declaration context | An instance/static method can only be overridden/hidden in a subclass. | An instance or static method can be overloaded in the same class or in a subclass. |
Binding of method call/polymorphic behavior | Calls to overridden instance methods are bound at runtime, and therefore exhibit polymorphic behavior. Calls to hidden static methods are bound at compile time and do not exhibit polymorphic behavior. | Calls are bound at compile time and do not exhibit polymorphic behavior. |