При объявлении метода класса как final какое ограничение получает наследник?
Наследник не может переопределить метод, объявленный как final, но может унаследовать его и вызывать. Компилятор отклонит попытку объявить в подклассе метод с тем же переопределяемым контрактом.
Наследование позволяет подклассам изменять поведение базового класса через переопределение методов. Однако некоторые методы должны оставаться неизменными: они могут поддерживать инварианты класса, безопасность состояния или обязательный алгоритм.
final выражает намерение автора класса закрыть конкретную точку расширения. Это также позволяет компилятору знать, что данный метод не будет переопределён в подклассе, хотя конкретные оптимизации не являются гарантией языка.
Без final подкласс может изменить поведение метода, даже если базовый класс рассчитывает на его исходную реализацию. Это опасно для методов, поддерживающих корректное состояние объекта, например для сброса внутренних ресурсов или проверки неизменяемых правил.
Если наследнику требуется другая реализация метода, объявление базового метода как final приведёт к ошибке компиляции. Поэтому final нужно применять только там, где переопределение действительно не должно быть частью расширения класса.
final у метода запрещает его override в любом подклассе. При этом метод остаётся доступным наследнику как обычный унаследованный метод, если его уровень доступа позволяет вызов.
В этом примере GuestSession может вызвать invalidate, но не может заменить его собственной реализацией. Попытка переопределить метод с override будет отвергнута компилятором.
final у метода не запрещает наследование самого класса и не делает остальные методы класса автоматически закрытыми для переопределения. Это отличается от final class, который запрещает создание любых подклассов.
Главный компромисс — потеря возможности полиморфной специализации именно этого метода. Взамен разработчик получает явно зафиксированный контракт и защиту от случайного изменения поведения в наследниках.
Базовый класс управляет жизненным циклом сетевого соединения. Метод завершения соединения освобождает ресурсы в определённом порядке, поэтому его делают final. Подклассам оставляют отдельные обычные методы для настройки логирования или подготовки данных.
Вариант без final даёт больше гибкости, но подкласс может переопределить завершение и забыть освободить ресурс. Вариант с final ограничивает расширение, зато ошибка обнаруживается на этапе компиляции, а жизненный цикл остаётся единым.
Выбор final оправдан, если корректность метода является инвариантом базового класса. Если же разные реализации являются штатной частью дизайна, метод закрывать нельзя — лучше использовать переопределение или другой механизм композиции.
1. Запрещает ли final вызов метода через ссылку на базовый класс?
Нет. final запрещает только переопределение. Метод можно вызвать через экземпляр подкласса или через ссылку на базовый тип, если метод доступен по уровню доступа.
2. Делает ли final весь класс неизменяемым?
Нет. final у метода ограничивает наследование поведения только этого метода. Свойства объекта по-прежнему могут изменяться согласно их объявлению, а другие методы могут оставаться переопределяемыми.
3. Чем final у метода отличается от final class?
final у метода запрещает переопределить один конкретный метод, но подклассы всё ещё разрешены. final class запрещает наследование самого класса, поэтому в таком классе невозможно переопределить ни один его метод через подкласс.