Урок №160. Сокрытие методов родительского класса

  Юрий  | 

  Обновл. 12 Окт 2020  | 

 10809

 ǀ   3 

Язык C++ предоставляет возможность изменить спецификатор доступа родительского члена в дочернем классе. Это делается с помощью «using-объявления». Например, рассмотрим следующий класс Parent:

Поскольку Parent::printValue() объявлен как protected, то он доступен только другим членам Parent и своим дочерним классам. Для других объектов доступ к нему закрыт.

Определим класс Child, который изменяет спецификатор доступа printValue() с protected на public:

Это означает, что следующий код выполнится без ошибок:

Здесь есть два примечания:

   Во-первых, вы можете изменить спецификаторы доступа только для тех членов родительского класса, к которым есть доступ у дочернего класса. Вы не сможете изменить спецификатор доступа члена родительского класса с private на protected или public, поскольку дочерний класс не имеет доступа к членам private родительского класса.

   Во-вторых, начиная с C++11 использование «using-объявления» является предпочтительным способом изменения спецификаторов доступа. Однако вы также можете использовать «access-объявление». Это работает идентично «using-объявлению», только без ключевого слова using. Сейчас этот способ считается устаревшим, но, проглядывая более старый код, вы можете увидеть «access-объявления», поэтому об этом стоит знать.

Сокрытие родительских методов в дочернем классе

В языке C++ невозможно удалить или ограничить функционал родительского класса, кроме как с помощью непосредственного изменения исходного кода. Однако в дочернем классе вы можете скрыть функционал, существующий в родительском классе, так чтобы к нему нельзя было получить доступ через объекты дочернего класса. Это делается путем изменения соответствующих спецификаторов доступа.

Например, вы можете сделать открытый член родительского класса закрытым:

Это позволяет инкапсулировать данные родительского класса в дочернем классе. В качестве альтернативы можно использовать наследование типа private, что приведет к тому, что все наследуемые члены public и protected класса Parent станут private в классе Child.

Вы также можете закрыть родительские методы в дочернем классе, используя ключевое слово delete:

Таким образом, компилятор будет жаловаться, если мы попытаемся вызвать метод getValue() через объект класса Child. Однако через объект родительского класса всё будет работать, так как мы «удалили» getValue() только в дочернем классе.


Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (104 оценок, среднее: 4,96 из 5)
Загрузка...

Комментариев: 3

  1. Аватар Kris:

    По-моему, это не чистая инкапсуляция методов. Даже если мы напишем в классе Child так:

    Мы все равно сможем обратиться к этому методу так:

    Поэтому, это не чистая инкапсуляция. Хотя, вроде бы, если Parent позволяет обращаться к getValue(), то это значит, что нет смысла ругаться на "чистоту инкапсуляции", ибо изначально ее как таковой и не было. В общем, как-то так.

  2. Аватар Nikita:

    А через методы дочернего класса, удаленный метод родительского класса все ровно работает. Почему?

  3. Аватар kmish:

    Еще можно скрыть родительский метод его переопределением. Ну это так, до кучи:

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *