Java Notes
Complete guide to the super keyword in Java — accessing parent class members, calling parent constructors, resolving method hiding, and understanding the super chain in inheritance hierarchies.
The super keyword is a reference to the parent (super) class of the current object. It lets you access parent class members that have been hidden or overridden by the child class.
While this refers to "myself," super refers to "my parent's version."
Three Uses of super
| Usage | Syntax | Purpose |
|---|---|---|
| Access parent field | super.fieldName | When child has same-named field |
| Call parent method | super.methodName() | When child overrides the method |
| Call parent constructor | super(args) | Initialize parent's portion of object |
Use Case 1: Calling Parent Constructor — super()
When you create a child object, the parent's portion must be initialized first. super() calls the parent's constructor:
public class Vehicle {
protected String brand;
protected int year;
protected double fuelCapacity;
public Vehicle(String brand, int year, double fuelCapacity) {
this.brand = brand;
this.year = year;
this.fuelCapacity = fuelCapacity;
System.out.println("Vehicle constructor: " + brand + " (" + year + ")");
}
}
public class Car extends Vehicle {
private int doors;
private String transmission;
public Car(String brand, int year, double fuelCapacity, int doors, String transmission) {
super(brand, year, fuelCapacity); // MUST be first statement
this.doors = doors;
this.transmission = transmission;
System.out.println("Car constructor: " + doors + " doors, " + transmission);
}
@Override
public String toString() {
return year + " " + brand + " | " + doors + " doors | " + transmission
+ " | " + fuelCapacity + "L tank";
}
}
public class ElectricCar extends Car {
private double batteryCapacity;
private int range;
public ElectricCar(String brand, int year, int doors, double battery, int range) {
super(brand, year, 0, doors, "Automatic"); // Electric cars have 0 fuel
this.batteryCapacity = battery;
this.range = range;
System.out.println("ElectricCar constructor: " + battery + " kWh");
}
@Override
public String toString() {
return super.toString() + " | Battery: " + batteryCapacity + "kWh | Range: " + range + "km";
}
}
public class Main {
public static void main(String[] args) {
ElectricCar tesla = new ElectricCar("Tesla", 2024, 4, 75.0, 350);
System.out.println("---");
System.out.println(tesla);
}
}Vehicle constructor: Tesla (2024) Car constructor: 4 doors, Automatic ElectricCar constructor: 75.0 kWh --- 2024 Tesla | 4 doors | Automatic | 0.0L tank | Battery: 75.0kWh | Range: 350km
Constructor Chain Rules
super()must be the first statement in the constructor- If you don't write
super(), Java insertssuper()(no-arg) implicitly - If parent has no no-arg constructor, you MUST explicitly call
super(args) - Constructor execution goes: Parent → Child (always top-down)
public class Parent {
// Only parameterized constructor
public Parent(String name) {
System.out.println("Parent: " + name);
}
}
public class Child extends Parent {
public Child() {
// super(); // ❌ Would fail — Parent has no no-arg constructor!
super("default"); // ✅ Must explicitly call parent's constructor
System.out.println("Child created");
}
}Use Case 2: Calling Parent Method — super.method()
When a child overrides a parent method, super.method() lets you call the parent's version:
public class Employee {
protected String name;
protected double baseSalary;
public Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
public double calculatePay() {
return baseSalary;
}
public String getDetails() {
return "Name: " + name + " | Base: $" + baseSalary;
}
}
public class Manager extends Employee {
private double bonus;
private int teamSize;
public Manager(String name, double baseSalary, double bonus, int teamSize) {
super(name, baseSalary);
this.bonus = bonus;
this.teamSize = teamSize;
}
@Override
public double calculatePay() {
return super.calculatePay() + bonus; // Parent's pay + bonus
}
@Override
public String getDetails() {
return super.getDetails() // Reuse parent's formatting
+ " | Bonus: $" + bonus
+ " | Team: " + teamSize
+ " | Total Pay: $" + calculatePay();
}
}
public class Director extends Manager {
private double stockOptions;
public Director(String name, double baseSalary, double bonus, int teamSize, double stockOptions) {
super(name, baseSalary, bonus, teamSize);
this.stockOptions = stockOptions;
}
@Override
public double calculatePay() {
return super.calculatePay() + stockOptions; // Manager's pay + stocks
}
@Override
public String getDetails() {
return super.getDetails() + " | Stock Options: $" + stockOptions;
}
}
public class Main {
public static void main(String[] args) {
Employee emp = new Employee("Alice", 60000);
Manager mgr = new Manager("Bob", 80000, 15000, 8);
Director dir = new Director("Carol", 120000, 30000, 25, 50000);
System.out.println(emp.getDetails());
System.out.println(mgr.getDetails());
System.out.println(dir.getDetails());
}
}Name: Alice | Base: $60000.0 Name: Bob | Base: $80000.0 | Bonus: $15000.0 | Team: 8 | Total Pay: $95000.0 Name: Carol | Base: $120000.0 | Bonus: $30000.0 | Team: 25 | Total Pay: $200000.0 | Stock Options: $50000.0
Use Case 3: Accessing Parent Field — super.field
When a child class declares a field with the same name as the parent (field hiding):
public class Shape {
protected String color = "red";
protected String type = "Shape";
}
public class Circle extends Shape {
protected String color = "blue"; // Hides parent's color
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public void showColors() {
System.out.println("My color (this.color): " + this.color); // blue
System.out.println("Parent color (super.color): " + super.color); // red
System.out.println("Type (inherited): " + type); // Shape (not hidden)
}
}
public class Main {
public static void main(String[] args) {
Circle c = new Circle(5.0);
c.showColors();
}
}My color (this.color): blue Parent color (super.color): red Type (inherited): Shape
Note: Field hiding is generally bad practice. Use method overriding instead.
super vs this Comparison
| Feature | this | super |
|---|---|---|
| Refers to | Current object | Parent class portion |
| Field access | this.field (current class) | super.field (parent class) |
| Method call | this.method() (current) | super.method() (parent) |
| Constructor | this(args) (same class) | super(args) (parent class) |
| In static context | ❌ Not allowed | ❌ Not allowed |
| Must be first in constructor | Yes (if used) | Yes (if used) |
| Can use both in one constructor | No | No |
Practical Pattern: Template Method with super
Base validation passed
JSON validation passed
Saved: {"NAME": "ALICE"}Multi-Level super Chain
super only goes ONE level up. You cannot write super.super.method():
public class A {
public void greet() {
System.out.println("Hello from A");
}
}
public class B extends A {
@Override
public void greet() {
System.out.println("Hello from B");
}
}
public class C extends B {
@Override
public void greet() {
super.greet(); // Calls B's greet()
// super.super.greet(); // ❌ COMPILE ERROR! Cannot skip levels
}
}
public class Main {
public static void main(String[] args) {
new C().greet();
}
}Hello from B
Common Mistakes
- Forgetting
super()when parent has no no-arg constructor:
``java class Parent { Parent(int x) { } // Only parameterized } class Child extends Parent { Child() { } // ❌ Error: implicit super() not available // Fix: Child() { super(0); } } ``
- Using
superin a static method:
``java public static void staticMethod() { super.toString(); // ❌ Cannot use super in static context } ``
- Trying to chain
super.super:
``java super.super.method(); // ❌ Not valid Java syntax ``
- Not calling super.method() in override when needed:
``java @Override public void init() { // Forgot super.init() — parent's initialization is skipped! doChildInit(); } ``
- Mixing
this()andsuper():
``java public Child(int x) { this(x, 0); // Calls another Child constructor super(x); // ❌ Cannot have both! Only one can be first. } ``
Best Practices
- Always call
super(args)explicitly — don't rely on implicitsuper() - Use
super.method()to extend behavior, not replace it entirely - Avoid field hiding — redesign if child needs a different value for the same concept
- Document when subclasses MUST call
super.method()in overrides - Keep constructor chains shallow — deep hierarchies are a code smell
Interview Questions
Q1: What is the difference between this() and super()? this() calls another constructor in the SAME class. super() calls a constructor in the PARENT class. Both must be the first statement, so you can't use both together.
Q2: What happens if you don't write super() in a constructor? The compiler inserts super() (no-arg) automatically. If the parent doesn't have a no-arg constructor, you get a compilation error.
Q3: Can you use super in a static method? No. super requires an instance context. Static methods have no instance.
Q4: Can super be used to call a grandparent's method? No. super.super.method() is not valid. super only accesses the immediate parent. If needed, the parent must expose the grandparent's functionality.
Q5: In what order do constructors execute in inheritance? Top-down: the root class constructor runs first, then each subclass in order. Object() → Animal() → Dog().
Q6: When is super keyword mandatory? When you need to: (1) call a parent's parameterized constructor, (2) access a parent's method that was overridden, or (3) access a parent's field that was hidden.
Q7: Can a constructor be inherited? No. Constructors are never inherited. Each class must define its own constructors and call the parent's using super().
Q8: Why can't we use super.super.method() in Java? Java deliberately doesn't allow this because it would break encapsulation. The child class should only know about its immediate parent, not the grandparent. If you need grandparent behavior, the parent should expose it through its own method.
Q9: What is the difference between super() implicit and explicit call? If you don't write any constructor call, Java inserts super() (no-arg) automatically. Explicit super(args) lets you choose which parent constructor to invoke. If the parent only has parameterized constructors, you MUST use explicit super(args) or you'll get a compile error.
Q10: Can we call super in a static method? No. super is an instance-level reference. Static methods don't belong to any instance, so there's no parent object to refer to. This is the same reason this cannot be used in static methods.
Q11: How does super work with method overriding and polymorphism? super.method() always calls the parent's version regardless of the runtime type. This is different from normal method calls which use dynamic dispatch. Inside a child class, super.display() is a direct (non-virtual) call to the parent's implementation.
Q12: What happens if you don't call super() and parent has no default constructor? Compilation error. The compiler tries to insert super() (no-arg) implicitly, but if the parent doesn't have a no-arg constructor, it fails. You must explicitly call super(args) with appropriate arguments matching one of the parent's constructors.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for super Keyword in Java.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Java Master Course topic.
Search Terms
java-master-course, java master course, java, master, course, oops, super, keyword
Related Java Master Course Topics