Java super keyword and Superclass

A superclass's reference variable can be assigned a reference to any subclass derived from that superclass. You will find this aspect of inheritance quite useful in a variety of situations. For example, consider the following example program:

/* Java Program Example - Java super Superclass */

class JavaProgram
{
    public static void main(String args[])
    {
   
        BoxWeight weightbox = new BoxWeight(5, 7, 9, 11.57);
        Box plainbox = new Box();
        
        double vol;
        
        vol = weightbox.volume();
        
        System.out.println("Volume of the weightbox is " + vol);
        System.out.println("Weight of the weightbox is " + weightbox.weight);
        System.out.println();
        
        /* assign BoxWeight reference to the Box reference */
        plainbox = weightbox;
        
        vol = plainbox.volume();    // OK, volume() defined in Box
        
        System.out.println("Volume of the plainbox is " + vol);
        
        /* the following statement is invalid because plainbox
         * doest not define a weight member          */
        
        // System.out.println("Weight of plainbox is " + plainbox.weight);
      
    }
}

Here, weightbox is a reference to the BoxWeight objects, and plainbox is a reference to the Box objects. Since BoxWeight is a subclass of the Box, it is permissible to assign plainbox is reference to the weightbox object.

It is important to understand that it is the type of the reference variable, not the type of the object that it refers to, that determines what members can be accessed i.e., when a reference to a subclass object is assigned to a superclass reference variable, you will have access only to those parts of the object defined by superclass. This is why plainbox can't access weight even when it refers to a BoxWeight object. If you think about it, this makes sense, because superclass has no knowledge of what a subclass adds to it. This is why the last line of code in the preceding code fragment is commented out. It is not possible for a Box reference to access the weight field, because the Box doest not define one.

Java super Keyword

In the preceding example, classes derived from the Box were not implemented as efficiently or as robustly as they could have been. For example, the constructor for the BoxWeight explicitly initializes the width, height, and the depth fields of Box. Not only does this duplicate code found in its superclass, which is inefficient, but it implies that a subclass must be granted access to these members. However, there will be times when you will want to create a superclass that keeps the details of its implementation of itself (i.e., that keeps its data members private). In this case, there would be no way for a subclass to directly access or initialize these variables on its own. Since encapsulation is a primary attribute of OOP, it is not surprising that Java provides a solution to this problem. Whenever a subclass needs to refer to its immediate superclass, it can do so by the use of super keyword.

The super has the following two general forms :

Let's examine both general forms of the super one by one.

A subclass can call a constructor defined by its superclass by use of the following forms of the super :

super(arg-list);

Here, arg-list specifies any arguments needed by the constructor in the superclass. The super() must always be the first statement executed inside a subclass constructor.

To see how the super() is used, consider the following improved version of the BoxWeight class :

/* BoxWeight now uses super to initialize its Box attributes */
      
class BoxWeight extends Box
{
   double weight;     // weight of the box
   
   /* initialize width, height, and depth using the super() */
   BoxWeight(double wei, double hei, double dep, double m)
   {
      super(wei, hei, dep);      // call the superclass constructor
      weight = m;
   }
}

Here, BoxWeight calls the super() with the argument wei, hei, and dep. This causes the Box constructor to be called, which initializes the width, height, and depth using these values. The BoxWeight no longer initializes these values itself. It only needs to initialize the value unique to it: weight. This leaves Box free to make these values private if desired.

Java super Keyword Example

In the preceding example, super() was called with three arguments. Since constructors can be overloaded, the super() can be called using any form defined by the superclass. The constructor executed will be the once that matches the arguments. For example, here is a complete implementation of the BoxWeight that provides constructors for the various ways that a box can be constructed. In each case, the super() is called using the appropriate arguments. Notice that the width, height, and depth have been made private within the Box.

/* Java Program Example - Java super Superclass
 * This is the complete implementation of the BoxWeight */
 
 class Box
 {
     private double width;
     private double height;
     private double depth;
     
     /* construct clone of an object */
     Box(Box obj)               // pass object to constructors
     {
         width = obj.width;
         height = obj.height;
         depth = obj.depth;
     }
     
     /* constructor used when all the dimensions specified */
     Box(double wei, double hei, double dep)
     {
         width = wei;
         height = hei;
         depth = dep;
     }
     
     /* constructor used when no dimensions specified */
     Box()
     {
         width = -1;         // use -1 to indicate
         height = -1;        // an uninitialized
         depth = -1;         // box
     }
     
     /* constructor used when the cube is created */
     Box(double len)
     {
         width = height = depth = len;
     }
     
     /* compute and return the volume */
     double volume()
     {
         return width * height * depth;
     }
 }
 
 /* BoxWeight is now fully implements all the constructors */
 class BoxWeight extends Box
 {
     double weight;      // weight of the box
     
     /* construct clone of an object */
     BoxWeight(BoxWeight obj)          // pass object to constructor
     {
         super(obj);
         weight = obj.weight;
     }
     
     /* constructor when all the parameters are specified */
     BoxWeight(double wei, double hei, double dep, double m)
     {
         super(wei, hei, dep);         // call the superclass constructor
         weight = m;
     }
     
     /* the default constructor */
     BoxWeight()
     {
         super();
         weight = -1;
     }
     
     /* constructor used when the cube is created */
     BoxWeight(double len, double m)
     {
         super(len);
         weight = m;
     }
 }
 
 class JavaProgram
 {
     public static void main(String args[])
     {
    
         BoxWeight mybox1 = new BoxWeight(100, 200, 150, 340.30);
         BoxWeight mybox2 = new BoxWeight(20, 30, 40, 0.086);
         BoxWeight mybox3 = new BoxWeight();          // default
         BoxWeight mycube = new BoxWeight(30, 20);
         BoxWeight myclone = new BoxWeight(mybox1);
         
         double vol;
         
         vol = mybox1.volume();
         System.out.println("Volume of the mybox1 : " + vol);
         System.out.println("Weight of the mybox1 : " + mybox1.weight);
         System.out.println();
         
         vol = mybox2.volume();
         System.out.println("Volume of the mybox2 : " + vol);
         System.out.println("Weight of the mybox2 : " + mybox2.weight);
         System.out.println();
         
         vol = mybox3.volume();
         System.out.println("Volume of the mybox3 : " + vol);
         System.out.println("Weight of the mybox3 : " + mybox3.weight);
         System.out.println();
         
         vol = myclone.volume();
         System.out.println("Volume of the myclone : " + vol);
         System.out.println("Weight of the myclone : " + myclone.weight);
         System.out.println();
         
         vol = mycube.volume();
         System.out.println("Volume of the mycube : " + vol);
         System.out.println("Weight of the mycube : " + mycube.weight);
         System.out.println();
       
     }
 }

When the above Java program is compile and executed, it will produce the following output:

java super superclass

Pay special attention to this constructor in BoxWeight :

/* construct clone of an object */
BoxWeight(BoxWeight obj)          // pass object to constructor
{
    super(obj);
    weight = obj.weight;
}

Notice that the super() is passed an object of type BoxWeight, not of type Box. This still invokes the constructor Box(Box obj). As mentioned earlier, a superclass variable can be used to reference any object derived from that class. Thus, we are able to pass a BoxWeight object to the Box constructor. Of course, Box only has knowledge of its own members.

Let's review the key concepts behind the super(). When a subclass calls the super(), it is calling the constructor of its immediate superclass. Thus, the super() always refers to the superclass immediately above the calling class. This is true even in a multilevelled hierarchy. Also, the super() must always be the first statement executed inside a subclass constructor.

super keyword (second form)

The second form of super acts somewhat like this, except that it always refers to the superclass of the subclass in which it is used. This usage has the following general form :

super.member

Here, member can be either a method or an instance variable.

This second form of the super is most applicable to situations in which the member names of a subclass hide the members by the same name in the superclass. Consider the following simple class hierarchy:

/* Java Program Example - Java super Superclass 
 * This program use super to overcome name hiding */
 
 class A
 {
     int i;
 }
 
 /* create a subclass by extending the class A */
 class B extends A
 {
     int i;        // this i hides the i in A
     
     B(int a, int b)
     {
         super.i = a;        // i in A
         i = b;              // i in B
     }
     
     void show()
     {
         System.out.println("i in superclass : " + super.i);
         System.out.println("i in subclass : " + i);
     }
 }
 
 class JavaProgram
 {
     public static void main(String args[])
     {
    
         B subobj = new B(10, 20);
         
         subobj.show();
       
     }
 }

When the above Java program is compile and executed, it will produce the following output:

java super

Although the instance variable i in B hides the i in A, super allows access to i defined in the superclass. As you will see, the super can also be used to call the methods that are hidden by a subclass.

Java Online Test


« Previous Tutorial Next Tutorial »