super is one of the heavily used keywords in Java programming language. It is used in the context of inheritance to refer the direct superclass of a subclass. It has two forms: super() and super. While deisgning a class:
- super() calls the constructor of the direct superclass.
- super refers to the direct superclass. So by using super keyword you can access the methods and instance variables of the direct superclass.
1. Uses of super()
It has only one use: that is to call the constructor of the direct superclass. It is generally used to initialize the fields inherited from the superclass. If used, it must be the first statment is a subclass constructor.
- Depending on the need, you can supply parameters to super as super(parameter-list) or suppy no parameters at all like super().
class Machine { double fuelCapacity; Machine(){ System.out.println("Calling parameter-less constructor"); fuelCapacity = 3; } Machine(double f){ System.out.println("Calling constructor with parameter"); fuelCapacity = f; } } class Vehicle extends Machine { double speed; // Constructor Vehicle(double s){ /* Calls the parameter-less constructor Machine() of the superclass which initializes the fields with default values. */ super(); speed = s; } // Another Constructor Vehicle(double s, double f){ /* Calls the parametrized constructor Machine(double f) of the superclass which initializes the fields with supplied values. */ super(f); speed = s; } } public class Super_Demo_1 { public static void main(String[] args){ Vehicle v1 = new Vehicle(4); System.out.println("Vehicle's speed: " + v1.speed + ", fuelCapacity: " + v1.fuelCapacity); System.out.println(); Vehicle v2 = new Vehicle(80, 100); System.out.println("Vehicle's speed: " + v2.speed + ", fuelCapacity: " + v2.fuelCapacity); } }
Output :
Calling parameter-less constructor Vehicle's speed: 4.0, fuelCapacity: 3.0 Calling constructor with parameter Vehicle's speed: 80.0, fuelCapacity: 100.0
- super(parameter-list) calls the constructor of the superclass that matches the parameter-list. The basis for matching is number and type of the parameters in the parameter-list.
class FourWheeler { double fuelCapacity; double speed; FourWheeler(double f){ System.out.println("Calling constructor with one parameter"); fuelCapacity = f; speed = 100; } FourWheeler(double f, double s){ System.out.println("Calling constructor with two parameter"); fuelCapacity = f; speed = s; } } class Car extends FourWheeler { String type; Car(String t, double f){ // Calls superclass constructor having one argument of type double super(f); type = t; } Car(String t, double f, double s){ // Calls superclass constructor having two arguments of type double super(f, s); type = t; } } public class Super_Demo_2 { public static void main(String[] args){ Car c1 = new Car("Sedan", 85); System.out.println("Car c1: type = " + c1.type + ", fuelCapacity = " + c1.fuelCapacity + ", speed = " + c1.speed); System.out.println(); Car c2 = new Car("SUV", 125, 225); System.out.println("Car c2: type = " + c2.type + ", fuelCapacity = " + c2.fuelCapacity + ", speed = " + c2.speed); } }
Output :
Calling constructor with one parameter Car c1: type = Sedan, fuelCapacity = 85.0, speed = 100.0 Calling constructor with two parameter Car c2: type = SUV, fuelCapacity = 125.0, speed = 225.0
- If subclass doesn’t call the superclass constructor explicitly, the compiler inserts parameter-less super() as the first statement inside the subclass constructor. If the superclass doesn’t have a parameter-less constructor, you will get compilation error.
class TwoWheeler { double fuelCapacity; TwoWheeler(){ System.out.println("Parameter-less Constructor called"); fuelCapacity = 10; } } class MotorCycle extends TwoWheeler { double speed; double weight; MotorCycle(double s){ /* Implicit Use: Doesn't explicitly calls super() but compiler inserts super() during compilation. */ speed = s; weight = 100; } MotorCycle(double s, double w){ // Explicit Use: Explicitly calls super(). super(); speed=s; weight=w; } } public class Super_Demo_3 { public static void main(String[] args){ MotorCycle m1 = new MotorCycle(150); System.out.println("m1: speed = " + m1.speed + ", weight = " + m1.weight + ", fuelCapacity = " + m1.fuelCapacity); System.out.println(); MotorCycle m2 = new MotorCycle(150, 200); System.out.println("m2: speed = " + m2.speed + ", weight = " + m2.weight + ", fuelCapacity = " + m2.fuelCapacity); } }
Output :
Parameter-less Constructor called m1: speed = 150.0, weight = 100.0, fuelCapacity = 10.0 Parameter-less Constructor called m2: speed = 150.0, weight = 200.0, fuelCapacity = 10.0
In both the subclass constructors, parameter-less superclass constructor was called.
Note: Like classes, super() can be chained. super() calls the immediate superclass which can have super() that in turn calls its immediate superclass and so on.
2. Uses of super
Super can acess the public and protected members of the superclass. (private members stay hidden)
- super can be used to access the instance variables of the superclass.
- super can be used to acess the methods defined in the superclass. As such it can be used to call the overridden methods of the superclass class.
2.1 super can be used to access the instance variables of the superclass.
class Fruit { String taste; String color; } class Mango extends Fruit { String color; Mango(){ // Two variables of name color: (1)subclass (2)superclass variable // Initializing subclass variable color = "Yellow"; // Initializing superclass variable super.color = "Green"; // Only one variable of name taste. i.e. superclass variable // Since no overriding happens, it can be accessed directly taste = "Sweet"; // Or by using super. Both are same and point to the same variable. super.taste = "Sour"; } void printColor(){ System.out.println("color: "+ color +", super.color: "+ super.color); } void printTaste(){ System.out.println("taste: "+ taste +", super.taste: "+ super.taste); } } public class Super_1 { public static void main(String[] args){ Mango m = new Mango(); m.printColor(); m.printTaste(); } }
Output :
color: Yellow, super.color: Green taste: Sour, super.taste: Sour
taste field is only defined in the superclass. The statement taste = “Sweet”; assigns value “Sweet” to variable taste. Then statement super.taste = “Sour”; assigns value “Sour” to the same variable taste.
The variable taste is defined in the superclass but you can access it without using super because there is no variable with the same name in the subclass.
2.2 super can be used to access the overridden methods of the superclass.
If a method of the superclass is overriden in the subclass, you can access the superclass method by using the super keyword(as super.method_name()).
class Flower { void getFeature(){ System.out.println("Superclass: Have Petals"); } void getColor(){ System.out.println("Superclass: Red"); } } class Rose extends Flower { // Overriding parent class method void getFeature(){ System.out.println("Subclass: Have Thorns"); } Rose(){ // Method getFeature() is overridden. // Calls the method definition from subclass getFeature(); // Calls the method definition from superclass super.getFeature(); // Method getColor() is not overridden. /* So super is optional. getColor() automatically calls superclass definition. */ // Both statements are equivalent. getColor(); super.getColor(); } } public class Super_2 { public static void main(String[] args){ Rose r = new Rose(); } }
Output :
Subclass: Have Thorns Superclass: Have Petals Superclass: Red Superclass: Red
Method getFeture() is overridden in the subclass. So by calling getFeature(); , you call the method defined inside the subclass. By calling super.getFeature(); , you call the method defined inside the superclass.
Method getColor() is only defined inside the superclass. So you can access it even without using the super keyword. So both of the method calls getColor(); and super.getColor(); result in calling the same method definition.
3. Points to Remember
- You cannot use this() and super() inside the same constructor. This is because both of them need to be first statement inside the constructor.