Java

Super Keyword in Java

The keyword super is used in the inheritance of Java classes. In Java, the superclass is the parent class of a current class. The current class is the child class (subclass) of the superclass. There is the possibility of the grandchild and great-grandchild classes going downwards. The parent class is the direct superclass of the current class. The grandparent class is not the direct superclass of the current class. This article explains the use of the keyword, super in Java. It begins by presenting a parent class, a child of the parent class, and a grandchild of the parent class. Then it shows how the word, super, fits into the hierarchy. The hierarchy below forms a form of the Calculator.

Article Content

Recall of Java Inheritance

Consider the following class:

    class Cparent {
        int a;
        int b;
        int add() {
            return a + b;
        }
    }

This class has two properties: a and b. In Java, properties are called fields. This class has one method that adds two numbers, which are the field values. The name of the class is Cparent, with the preceding C, for Calculator. The following code segment in the main() method, outputs 5:

            Cparent parent =  new Cparent();
            parent.a = 2;
            parent.b = 3;
            int rAdd = parent.add();
            System.out.println(rAdd);

Consider the following class, which is the subclass of the above class (Cparent):

    class Cchild extends Cparent {
        int c;
        int multiply() {
            return a * c;
        }
    }

Note the use of the keyword extends. This class has the field, c, and the method, multiply(). The class inherits the fields, ‘a’ and b, and the method, add(). However, if the field value for ‘a’ or b is to be used for this current instantiated object (child object), it still needs to be reassigned a value. For this class, the value of ‘a’ inherited is multiplied by the class’s field value of c. The name of this class is Cchild, with the preceding C, for Calculator. The following code segment in the main() method suits this class:

            Cchild child =  new Cchild();
            child.a = 2;
            child.c = 4;
            int rMult = child.multiply();
            System.out.println(rMult);

The output is 8. Note that, though the field ‘a’ was inherited, it still had to be reassigned a value; in this case, the same value.

Consider the following class, which is the subclass of the above class, Cchild:

    class CgrandChild extends Cchild {
        int d;
        int divide() {
            return a / d;
        }
    }

Note the use of the keyword extends. This class has the field, d, and the method, divide(). The class inherits the members, ‘a’, b, and add() from the Cchild class, which inherited them from the Cparent class. It also inherits the members, c, and multiply() from the Cchild class. However, if the field value for ‘a’ or b or c, from the parent or grandparent classes, is to be used for this current instantiated object (grandchild object), it still needs to be reassigned a value. For this class, the value of ‘a’ inherited is divided by the class’s field value of d. The name of this class is CgrandChild, with the preceding C, for Calculator. The following code segment in the main() method suits this class:

            CgrandChild gChild =  new CgrandChild();
            gChild.a = 2;
            gChild.d = 2;
            int rDiv = gChild.divide();
            System.out.println(rDiv);

The output is 1. Note that, though the field ‘a’ was inherited, it still had to be reassigned a value; in this case, the same value, 2.

Use of the super Keyword

Field and super
In the above program, the value for the field, ‘a’ was set three times, once for the parent object, once for the child object, and once for the grandchild object. To avoid this resetting each time, the value of 2 can be assigned once, in the parent class implementation (definition) as follows:

    class Cparent {
        int a = 2;
        int b;

        int add() {
            return a + b;
        }
    }

This solves the problem of resetting for each descendant object. In the descendant classes, the field, ‘a’ is simply referred to (normally).

To access the value of an inherited field, the super keyword has to be used in the descendant class implementation of interest, as follows:

super.fieldName

The following code segment shows how the name ‘a’ has been accessed, in a new Cchild implementation:

    class Cchild extends Cparent {
        int p = super.a;
        int c;
        int multiply() {
            return p * c;
        }
    }

The class, Cchild, now has its own name, p instead of ‘a’. And so the statement in the add() method,

            return a * c;

is now,

            return p * c;

In a similar way, the class implementation, CgrandChild can have ‘a’ replaced by q, as follows:

    class CgrandChild extends Cchild {
        int q = super.a;
        int d;
        int divide() {
            return q / d;
        }
    }

Note: Inheritance takes place in all descendant classes. The ‘a’ field and the add() method are inherited into the Cchild class and into CgrandChild class.

Method and super
Similarly, an inherited field can be accessed in the implementation of a descendant class; an inherited method can also be accessed in a descendant class, using the super keyword. The syntax is:

super.methodName()

The implementation of the original Cchild class can be modified as follows:

    class Cchild extends Cparent {
        int c;
        int sum = super.add();
        int multiply() {
            return a * c;
        }
    }

Note that use of super. The inherited add() method is now seen as a “sum” in the implementation of Cchild. The field c, and the method, multiply(), are still there. A code segment for addition in the main() method that suits this modified Cchild class is:

            Cchild child =  new Cchild();
            int rSum = child.sum;
            System.out.println(rSum);

The output is 5, assuming that the parent class was modified with:

        int a = 2;
        int b = 3;

Constructor and super
The default constructor, which is not implemented, is inherited into every descendant class and does not have to be accounted for in the implementation of the descendants and in the main() method. However, once a parent class has a custom constructor, the rest of its descendants need to have a similar constructor. Consider the parent class, with a custom constructor, as follows:

    class Cparent {
        int a, b;
        public Cparent(int x, int y) {
            a = x; b = y;
        }
        int add() {
            return a + b;
        }
    }

The fields of ‘a’ and b are declared without assignment. The constructor does the assignment. The child class needs to have the same or a similar constructor. The corresponding child class for the original calculator hierarchy can be:

    class Cchild extends Cparent {
        Cchild(int x, int y) {
            super(x, y);
        }
        int c;
        int multiply() {
            return a * c;
        }
    }

The constructor here is the same as that of the parent. The body of the constructor here just has:

super(x, y);

which just calls the constructor of the parent, with the arguments received. “super” here represents the parent class constructor. This is another use of super. There is no modification in this child constructor. The corresponding grandchild class for the original calculator hierarchy can be:

    class CgrandChild extends Cchild {
        int d;
        CgrandChild(int x, int y, int z) {
            super(x, y);
            d = z;
        }
        int divide() {
            return a / d;
        }
    }

The constructor here is modified. It has the same x and y parameters and an extra parameter, z. z is to assign the value for d, the divisor. The body for the constructor begins by calling the constructor of the parent class. Then the field for the divisor is assigned. The following code segment in the main() method suits this class:

            CgrandChild gChild =  new CgrandChild(2, 3, 2);
            int rDiv = gChild.divide();
            System.out.println(rDiv);

The output for this is 1.

Conclusion

Super will look for something in the immediate parent class. If it does not see it there, it will look for it in the grandparent class. If it does not see it there, it will look for it in the great grandparent class; and so on, until it either sees it or it does not see it. “super” is usually used within the implementation of a subclass. It is used for field, method, and constructor. The direct superclass is the parent class. The grandparent class is a superclass, but not the direct superclass. Next, the reader should understand the use of “super” with nested classes – see later.

About the author

Chrysanthus Forcha

Discoverer of mathematics Integration from First Principles and related series. Master’s Degree in Technical Education, specializing in Electronics and Computer Software. BSc Electronics. I also have knowledge and experience at the Master’s level in Computing and Telecommunications. Out of 20,000 writers, I was the 37th best writer at devarticles.com. I have been working in these fields for more than 10 years.