Наследование и переопределение членов
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Переопределение

О возможности перегрузки методов мы уже говорили – имеется в виду объявление нескольких методов класса с одним и тем же именем, но с различными сигнатурами. Термин переопределение метода означает замещение версии метода, объявленной в базовом классе, новой, с точно такой же сигнатурой.

Перегружая ( overloading ) унаследованный метод базового класса, мы просто добавляем в объявление производного класса новый метод с тем же именем, но другой сигнатурой. Переопределяя ( overriding ) метод, мы изменяем его реализацию, так что при обращении к методу объекта производного класса будет вызвана именно новая версия метода, а не «старая», принадлежащая базовому классу.

При переопределении метода в производном классе его наименование и сигнатура должны оставаться теми же, что объявлены в базовом классе. Если два метода различаются только, скажем, типом возвращаемого значения, это считается ошибкой и компилятор на неё укажет.

Переопределённые методы обладают собственными признаками доступа. В производном классе разрешается изменять уровень доступа к унаследованному методу базового класса, но только в сторону повышения. Метод, объявленный как protected в базовом классе, в производном может быть переопределён вновь с тем же модификатором protected (и это обычная практика) либо помечен как public , но объявлять его посредством private или полностью лишать явного модификатора доступа (предусматривая признак доступа уровня пакета) нельзя. Уменьшение возможности доступа к методу относительно того уровня, который определён в базовом классе, нарушает контракт базового класса, и экземпляр производного класса теперь не может быть использован в контексте, предусматривающем применение базового.

При переопределении метода позволяется изменять и другие модификаторы. Признаками synchronized, native и strictfp разрешено манипулировать совершенно свободно, поскольку они относятся исключительно к особенностям внутренней реализации метода. Переопределённый метод может быть помечен как final, но тот, который подвергается переопределению (это вполне очевидно) – нет. Метод экземпляра производного класса не может обладать той же сигнатурой, что и статический унаследованный метод, и наоборот. Переопределённый метод в производном классе, однако, может быть снабжён модификатором abstract даже в том случае, если в базовом этого предусмотрено не было.

В производном классе допускается иная трактовка возможности и необходимости использования модификатора final по отношению к параметрам метода: модификатор final не входит в состав сигнатуры и обусловливает только особенности внутренней реализации метода. Допускаются и различия методов базового и производного классов, касающиеся предложения throws, если только каждый из типов исключений, перечисленных в объявлении переопределённого метода, совпадает с одним из тех, которые заданы в объявлении «базового» метода, либо является производным от любого из них. Другими словами, каждый их типов исключений в объявлении throws переопределённого метода должен быть полиморфным образом совместим хотя бы с одним из типов, указанных в объявлении метода, который принадлежит базовому классу. Это означает, что предложение throws переопределённого метода может содержать меньше типов, чем перечислено в объявлении метода базового класса, либо больше специфических производных типов, либо то и другое одновременно. В переопределённом методе допускается и отсутствие предложения throws – в этом случае предполагается, что метод не должен генерировать объявляемые исключения.

Сокрытие полей

Поля класса не допускают переопределения – их можно только скрыть (hide). Когда в производном классе объявляется поле с тем же именем, что и в базовом, прежнее продолжает существовать, но перестаёт быть доступным, если обращаться к нему непосредственно по имени. Чтобы сослаться на одноимённое поле, принадлежащее базовому классу, следует воспользоваться служебным словом super либо сослаться на текущий объект с приведением типа к базовому классу.

Дата: 2019-02-19, просмотров: 225.