Ответ
Переопределение (overriding) позволяет подклассу предоставить свою реализацию метода, уже определённого в суперклассе.
Основные правила:
- Сигнатура: Имя метода и список параметров (типы, порядок) должны в точности совпадать.
- Возвращаемый тип: Должен быть тем же или ковариантным (подтипом) возвращаемого типа метода родителя.
- Модификатор доступа: Не может быть более строгим, чем у переопределяемого метода (можно ослабить:
protected->public). - Модификатор
final: Метод, объявленный какfinal, переопределить нельзя. - Модификатор
static: Статические методы не переопределяются, а скрываются. - Модификатор
private: Приватные методы не видны в подклассе, поэтому не переопределяются. - Исключения: Переопределённый метод может:
- Не объявлять никаких проверяемых исключений (checked exceptions).
- Объявлять меньше или более конкретные (подклассы) проверяемые исключения.
- Объявлять любые непроверяемые исключения (unchecked exceptions).
Пример корректного переопределения:
class Vehicle {
protected String getDetails() {
return "Generic Vehicle";
}
}
class Car extends Vehicle {
@Override // Аннотация помогает компилятору проверить правила
public String getDetails() { // Модификатор доступа ослаблен (protected -> public)
return "Sports Car";
}
}
Аннотация @Override — строго рекомендуется. Она заставляет компилятор проверить, действительно ли метод переопределяет метод суперкласса, и предотвращает ошибки в именах или сигнатурах.