super

super даёт доступ к части поведения текущего объекта, объявленной в непосредственном суперклассе. Это не отдельный объект родителя.

class Message {
    private final String text;
 
    Message(String text) {
        this.text = Objects.requireNonNull(text);
    }
 
    String render() {
        return text;
    }
}
 
class ImportantMessage extends Message {
    ImportantMessage(String text) {
        super(text);
    }
 
    @Override
    String render() {
        return "! " + super.render();
    }
}

Два назначения

  • super(args) вызывает конструктор непосредственного родителя;
  • super.method() или super.field обходит переопределение/сокрытие в текущем классе.

Вызов конструктора super(...) должен быть первым оператором. Если его нет, компилятор вставляет super(). Это сработает только при доступном конструкторе родителя без аргументов.

Конструкторы не наследуются и не переопределяются. При создании наследника сначала инициализируется родительская часть объекта, затем дочерняя.

Ошибки

  • вызов переопределяемого метода из конструктора родителя может попасть в метод наследника до инициализации его полей;
  • private-члены родителя недоступны напрямую даже через super;
  • статические методы через super всё равно не становятся полиморфными;
  • множественного наследования классов в Java нет, поэтому super относится к одному непосредственному родителю.

На собеседовании

Что произойдёт, если у родителя нет конструктора без аргументов? Наследник обязан явно вызвать подходящий super(args).

Можно ли использовать super.super? Нет.

Является ли super ссылкой на другой объект? Нет, это специальная форма доступа к родительской реализации текущего объекта.

Связано: this Java, Блоки инициализации, Полиморфизм.