May 31, 2015

Method and Variable shadowing in Java

Method Shadowing

In java only instance method of parent class can be overridden, not static methods. Below example shows method shadowing in java.

class Parent {
 private static String hideMe = "HIDDEN-GEM-PARENT";

 public static void show() {
  System.out.println("show():HIDDEN - GEM is " + hideMe);
 }

 public void display() {
  System.out.println("display():HIDDEN - GEM is " + hideMe);
 }
}

class Child extends Parent {
 private static String hideMe = "HIDDEN-GEM-CHILD";

 // @Override - Not allowed, only instance method can be overridden
 public static void show() {
  System.out.println("show():HIDDEN - GEM is " + hideMe);
 }

 @Override
 public void display() {
  System.out.println("display():HIDDEN - GEM is " + hideMe);
 }
}

public class ShadowingMethods {

 /**
  * @param args
  */
 @SuppressWarnings("static-access")
 public static void main(String[] args) {
  Parent child = new Child();
  child.show(); // calls Parent class static methods, not Overridden
  child.display(); // calls Child class methods, since Overridden
 }
}

Sample output :-
show():HIDDEN - GEM is HIDDEN-GEM-PARENT
display():HIDDEN - GEM is HIDDEN-GEM-CHILD

child.show() - calls parent class methods, since it is static method. In java static method is not overridden it is shadowed by Child class (If we @override above static method created, compiler reports error).



Variable Shadowing:-


package javacore;

public class ShadowVariable {

 private String strVar = "OuterMostString";

 class FirstLevel {

  private String strVar = "FirstLevelString";

  class SecondLevel {
   private String strVar = "SecondLevelString";

   void displaySecondLevel(String strVar) {
    System.out.println("strVar  = " + strVar);
    System.out.println("this.strVar = " + this.strVar);
    System.out.println("ShadowVariable.this.x = "
      + FirstLevel.this.strVar);
    System.out.println("ShadowVariable.this.x = "
      + ShadowVariable.this.strVar);
   }
  }
 }

 public static void main(String[] args) {
  ShadowVariable st = new ShadowVariable(); 
  ShadowVariable.FirstLevel l1 = st.new FirstLevel();
  ShadowVariable.FirstLevel.SecondLevel l2 = l1.new SecondLevel();
  l2.displaySecondLevel("MethodArgumentVariable");
 }
}

Sample Output: 

strVar  = MethodArgumentVariable
this.strVar = SecondLevelString
ShadowVariable.this.x = FirstLevelString
ShadowVariable.this.x = OuterMostString

If a declaration of a type (such as a member variable or a parameter name) in a particular scope (such as an inner class or a method definition) has the same name as another declaration in the enclosing scope, then the declaration shadows the declaration of the enclosing scope. You cannot refer to a shadowed declaration by its name alone. (Source)

In order to access corresponding member variable of class we have to use <classname>.this as scope resolution, based on context variable is referred. 
Location: Hyderabad, Telangana, India