Что такое наследование
Что проверяют
Знаете ли вы правила языка (что наследуется, что скрывается, что переопределяется) и понимаете ли, почему наследование реализации сегодня применяют осторожно.
Как отвечать
Через extends подкласс получает доступные ему поля и методы предка. Класс наследует ровно один класс, но реализует сколько угодно интерфейсов, а методы по умолчанию в интерфейсах дают множественное наследование поведения, но не состояния.
Что назвать точно:
- переопределяются только методы экземпляра; статические скрываются, приватные и финальные не переопределяются вовсе;
- поля не переопределяются, а скрываются, и выбираются по типу переменной, а не по фактическому объекту;
- при переопределении нельзя сужать видимость и расширять список проверяемых исключений, зато можно сузить возвращаемый тип;
- конструкторы выполняются от предка к потомку, а поля подкласса инициализируются уже после вызова конструктора предка.
Последний пункт даёт классическую ловушку:
class Base {
Base() { init(); }
void init() { }
}
class Child extends Base {
private List<String> items = new ArrayList<>();
@Override void init() { items.add("first"); }
}Конструктор предка зовёт переопределённый метод, когда items ещё не инициализировано, и создание объекта падает.
Хороший финал: наследование связывает классы жёстко, поэтому по умолчанию берут композицию и делегирование, а класс, не рассчитанный на наследование, закрывают через final или перечисляют допустимых наследников через sealed.
Где спотыкаются
Видят в наследовании способ переиспользовать код. Подкласс заводится ради двух удобных методов и вместе с ними принимает весь контракт предка, после чего любое изменение предка ломает потомков в неожиданных местах.
Пишут перегрузку вместо переопределения. Тип параметра чуть отличается, метод прекрасно компилируется, но не вызывается никогда. Аннотация @Override ловит это на компиляции, поэтому её ставят всегда.
Ломают сравнение в иерархии. Если предок сравнивает через instanceof, а потомок добавляет в сравнение своё поле, симметрия теряется: предок считает объекты равными, потомок нет, и коллекции начинают вести себя необъяснимо.