Saturday, February 21, 2009

Java Inheritance gotchas

Here are a few gotchas about inheritance in java. It is followed by an example which highlights some of these.
- private instance methods and variables are not inherited. Similarly, final instance methods and variables are not inherited. If you try it, you will get compile time error.
- Static methods and static variables cannot be inherited. If static methods are defined again in the sub class, it amounts to redefinition and has nothing to do with overriding. It is also called static method hiding. Similarly if static variables are defined again in the sub class it hides the static variables with same name in the super class.
-Similar to static variables , if instance variables are defined again in subclass, it hides the variables with same name in the super class.
- For redefinition/hiding it is the same name that matters, the type and access modifiers can be different.
- Since static members(variables and methods) belong to a class and not an instance, it is always a good practice to access static members with class name. If they are called using reference type, the reference type and not the object type determines which static method will be called.
- Object type determines which overloaded method is called at runtime but reference type determines whether a method can be called i.e. if the method isn't defined in reference type definition, you will get a compile time error.
- Reference type and not the object type determines which instance variable is called at runtime.
- When you override a method, you can still get the original method by using super.thatMethod() .

Example:

//Super class
public class StringInstruments {

  public static String types = "Over 50 types of String Instruments are available today";
  protected String wholesaleManufacturer = "Thumbelina & Co";
  
  public static void superDefinition() {
    System.out.println("StringInstruments: Vibrating strings produce sound.");
  }
  
  public void playIt() {
    System.out.println("Pluck it or use the bow or strike it");
  }

}

//Sub class
class ClassicalViolin extends StringInstruments {
  
//Redefinition
  public static String types = "Only 1 type of Classical Violin exists today, though it comes in many sizes";

//Instance variable redefinition.
// If you want inheritance, have get and set for
//this member variable in the base class.
  int  wholesaleManufacturer = 8;
  
  //Static method hiding
  public static void superDefinition() {
    System.out.println("Violin: A String Instrument");
  }
  
//Overridden method
  @Override public void playIt() {
    System.out.println("Use the bow to play a Violin");
  }
}

//Test the above code
public class TestInstruments {
  public static void main(String[] args) {
    StringInstruments si = new ClassicalViolin();
    //Calls the static method of the reference type 
    si.superDefinition();
    
    //Calls the overridden method of the reference object
    si.playIt();
    
    //Accesses the static variable of the reference type 
    System.out.println(si.types);
    
    //Accesses the instance variable of the reference type
    System.out.println(si.wholesaleManufacturer);
    
    //Calls to static methods and static variables 
    //should be made using the classname to avoid confusion
    StringInstruments.superDefinition();
    ClassicalViolin.superDefinition();
    System.out.println(StringInstruments.types);
    System.out.println(ClassicalViolin.types);
    
    //Prints the instance variable defined in ClassicalViolin
    System.out.println(new ClassicalViolin().wholesaleManufacturer);
    
  }
}

No comments:

Post a Comment