🧬 Inheritance & Polymorphism · Intermediate

super in Java

super.method() and super(...) constructor calls.

🧩 The mysteryA child class overrides hi() but wants the parent's greeting plus a little extra. So it calls hi() from inside hi()... and the program crashes. What's the escape hatch?

super: the parent part

Every subclass object contains a "parent part". **super.method() runs the parent's version** of a method, skipping the override. It's how an override *extends* behavior instead of replacing it.

🔮 Predict it

Add some milk

What does this print?

class Coffee {
    String desc() { return "coffee"; }
}
class Latte extends Coffee {
    String desc() {
        return super.desc() + " + milk"; }
}
void main() {
    System.out.println(new Latte().desc());
}
  1. coffee
  2. coffee + milk
  3. + milk
Show the answer

coffee + milk. super.desc() reaches Coffee's version, and Latte's override adds to its result.

🔮 Predict it

Forget the super.

Same idea, one word missing. What happens?

class Base {
    String hi() { return "Hi"; }
}
class Kid extends Base {
    String hi() { return hi() + "!"; }
}
void main() {
    System.out.println(new Kid().hi());
}
  1. Hi!
  2. !
  3. Throws StackOverflowError
Show the answer

It throws **StackOverflowError**. A plain hi() call dispatches to Kid's own hi() — which calls itself again, forever, until the call stack overflows. Only super.hi() reaches the parent.

super(...) in constructors

In a constructor, **super(...) calls a parent constructor** to initialize the inherited state.

class Animal {
    String name;
    Animal(String n) { name = n; }
}
class Cat extends Animal {
    Cat() { super("Tom"); } // name = "Tom"
}

The invisible super()

If a constructor doesn't call this(...) or super(...), the compiler **inserts super() — a call to the parent's no-arg constructor. If the parent doesn't have one, you must** call super(args) yourself.

A parent that needs a name

✗ Doesn't compile
class Cat extends Animal {
    Cat() {
        System.out.println("meow");
    }
}

Hidden super() — but Animal only has Animal(String).

✓ Fixed
class Cat extends Animal {
    Cat() {
        super("Tom");
        System.out.println("meow");
    }
}

Calls the constructor Animal actually has.

💼 In the real world

In real projects

Frameworks are full of "remember to call super" rules. On Android, an Activity's onCreate override must call super.onCreate(savedInstanceState) — forget it and the app crashes with SuperNotCalledException.

Key takeaways

  1. super.m() calls the parent's version of m()
  2. super(...) calls a parent constructor
  3. Without an explicit call, the compiler inserts super()
  4. If the parent has no no-arg constructor, you must call super(args)
🤯 Did you know?

super isn't a real reference you can store: Object p = super; doesn't compile. It only works as super.member or super(...).

Practice questions

What does this print?

class Base {
    String hi() { return "Hi"; }
}
class Kid extends Base {
    String hi() { return super.hi() + "!"; }
}
void main() {
    System.out.println(new Kid().hi());
}
  1. Hi
  2. Hi!
  3. !
  4. Hi!!
Check your answer

Hi!. Kid's override reuses the parent's result through super.hi() and adds an exclamation mark.

What does this print?

class Animal {
    String name;
    Animal(String n) { name = n; }
}
class Cat extends Animal {
    Cat() { super("Tom"); }
}
void main() {
    System.out.println(new Cat().name);
}
  1. null
  2. Tom
  3. Cat
  4. Compile error
Check your answer

Tom. Cat's constructor passes "Tom" to Animal's constructor with super(...), which stores it in the inherited name field.

Next: who's built first — the parent or the child? Constructor order in hierarchies.