An instance method defined in a subclass can override another instance method in the superclass when:
- Both have the same name
- Number and type of parameters is same
- Return type is same
The Hiding term is used in context of a class method that has the same signature as the corresponding class method in the superclass.
The difference between these two is that the overridden method gets invoked from the subclass while the hidden method may get invoked from either the superclass or the subclass, depending on how it is invoked.
Noncompliant Code Example
To differentiate between overriding and hiding, a common nomenclature is used. The method to be invoked is decided at either compile time (if the base method is static, as in this noncompliant example) according to the type of the qualifier or at run time otherwise (for non-static methods). A qualifier is a part of the invocation expression before the dot (for example, admin
and user
here).
This noncompliant example attempts to override a static method but fails to consider it as a hiding case. As a result the displayAccountStatus
method of the superclass gets invoked on both the calls. Moreover, expressions that are normally used for dynamic dispatch while overriding have been used even though this is impossible with static
methods.
class GrantAccess { public static void displayAccountStatus() { System.out.print("Account details for admin: XX"); } } class GrantUserAccess extends GrantAccess { public static void displayAccountStatus() { System.out.print("Account details for user: XX"); } } public class StatMethod { public static void choose(String username) { GrantAccess admin = new GrantAccess(); GrantAccess user = new GrantUserAccess(); if(username.equals("admin")) admin.displayAccountStatus(); else user.displayAccountStatus(); } public static void main(String[] args) { choose("user"); } }
Compliant Solution
This compliant solution correctly classified this case as hiding and uses absolute class names GrantAccess
and GrantUserAccess
to clearly state the intent. Refrain from qualifying a static method invocation with an expression meant for dynamic dispatch.
class GrantAccess { public static void displayAccountStatus() { System.out.print("Account details for admin: XX"); } } class GrantUserAccess extends GrantAccess { public static void displayAccountStatus() { System.out.print("Account details for user: XX"); } } public class StatMethod { public static void choose(String username) { if(username.equals("admin")) GrantAccess.displayAccountStatus(); else GrantUserAccess.displayAccountStatus(); } public static void main(String[] args) { choose("user"); } }
Risk Assessment
Confusing overriding and hiding can produce unexpected results.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
MET00-J |
low |
unlikely |
high |
P1 |
L3 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[Tutorials 08]] Overriding and Hiding Methods
[[Bloch 05]] Puzzle 48: All I Get Is Static