How does the super keyword work in Java, and what is the difference between super(), super.field and super.method()?
super is a reference to the superclass of the current class. It has three distinct uses, and confusing them is a common source of errors.
super(...) is a constructor call. It invokes a constructor of the superclass, and it must be the first statement of the constructor body. If you omit it, the compiler inserts an implicit super() to the superclass's no-argument constructor — which is why a subclass whose superclass has no no-argument constructor fails to compile until you add an explicit super(...) call.
super.field reads a field of the superclass. It matters when the subclass declares a field with the same name: inside the subclass, the unqualified name refers to the subclass's field, and super.field reaches the other one. Note that super.field cannot be used on the left-hand side of an assignment, because assignment to a superclass field through super is not permitted — you have to call a superclass method instead.
super.method() calls the superclass implementation of a method. This is the useful one when you are overriding: you call the parent's version and add behaviour around it, instead of duplicating it.
public class Main {
public static void main(String[] args) {
Child child = new Child("Ada");
System.out.println("name : " + child.getName());
System.out.println("label : " + child.describe());
}
}
class Parent {
protected String name;
Parent(String name) {
this.name = name;
System.out.println("Parent constructor ran");
}
String describe() {
return "I am the parent";
}
}
class Child extends Parent {
private final String label;
Child(String name) {
super(name); // must be the first statement
this.label = "child of " + name;
System.out.println("Child constructor ran");
}
@Override
String describe() {
return super.describe() + " and I am the child";
}
String getName() {
return name; // inherited protected field
}
}The output shows both the ordering and the three uses. The parent's constructor runs before the child's, so the inherited name field is already set when the child constructor body executes. The describe override calls the parent implementation with super.describe() and appends its own text rather than replacing it.