C++. Наследование. Общие понятия. Использование модификаторов private, protected, public

Наследование. Общие понятия. Использование модификаторов private, protected, public при наследовании


Содержание


Поиск на других ресурсах:

1. Повторное использование кода. Наследование

Идея наследования в программировании взята из природы и начинается еще с 60-х годов 20 века. В языке C++ концепция классов существенно усиливается благодаря внедрению наследованию в классах. В природе наследование позволяет добавлять к родительским качествам новые навыки. В программировании наследование – это свойство класса получать программный код (навыки) другого (базового) класса, добавляя к нему свой собственный код, тем самым расширяя его возможности.

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

Наследование свойственно только классам и их характеристикам, а не переменным или функциям.

Проекты на языке C++ базируются на использовании конкретных классов, решающих поставленные задачи. Благодаря использованию наследования классы строятся постепенно, от базовых простых классов до специализированных классов, постепенно детализирующих решение. В итоге классы образуют иерархию классов. В этих иерархиях классы верхних уровней (базовые классы) описывают некоторые общие для всех характеристики, которые на нижних уровнях детализируются в унаследованных классах. Завершенный программный проект есть работоспособной системой, состоящей из иерархически связанных между собой классов. Количество классов в некоторых проектах может составлять десятки или сотни.

В отличие от некоторых языков программирования, в языке C++ разрешено множественное наследование. При множественном наследовании один класс может быть унаследован из нескольких базовых классов, получая их свойства и поведение.

В контексте понятия наследования определяется понятие повторного использования кода, которое в программировании на C++ определено двумя аспектами:

  • создание класса с целью получения экземпляров;
  • создание класса для его использования в качестве базового, передающего свои характеристики унаследованным классам.

Порождение кода от базового класса является эффективным способом использования уже написанного кода для собственных нужд. Наследование является одной из частей повторного использования кода.

 

2. Синтаксис объявления классов, образующих иерархию. Базовый класс и производный (унаследованный) класс

Для реализации наследования требуется наличие как минимум двух классов. Если в программе класс с именем B должен быть унаследован от класса с именем A, то объявление классов выглядит следующим образом:

class A
{
  // Элементы класса A
  // ...
};

class B : A
{
  // Составляющие элементы класса B
  // ...
};

В вышеприведенном объявлении класс B наследует часть характеристик или все характеристики класса A. Из класса B может быть унаследован другой (третий) класс, который получит часть или все характеристики классов A и B. Кроме того, из класса A могут быть унаследованы один или несколько классов, которые по отношению к классу B образуют параллельную ветвь иерархии. На рисунке 1 представлен один из возможных вариантов образования классами древовидной иерархии наследования.

 

C++. Наследование. Дерево наследования, созданное классамиРисунок 1. Наследование. Дерево наследования, созданное классами

 

3. Передача характеристик наследуемому классу. Варианты реализации. Ограничение и расширение доступа. Ключевые слова private, protected, public

Важным при наследовании является вопрос: как передать характеристики базового класса в унаследованный класс? Здесь C++ дает широкий спектр возможных вариантов реализации.

Для указания того, какие элементы базового класса должны быть доступны в унаследованном классе, используется механизм инкапсуляции. Основой этого механизма является использование ключевых слов private, protected, public для предоставления доступа или запрета доступа к элементам базового класса.

 

3.1. Взаимодействие двух классов. Доступ из унаследованного класса к элементам базового класса

Элемент базового класса (переменная, функция) может быть объявлен с одним из трех модификаторов доступа:

  • private (скрытый). В этом случае доступа к этому элементу из унаследованного класса нет;
  • protected (защищенный) – позволяет использовать элемент базового класса в унаследованном классе;
  • public (общедоступный) – в унаследованном классе действует так же, как protected.

На рисунке 2 показаны все 3 вида доступа для двух классов, образующих иерархию наследования. Демонстрируется доступ к переменной a базового класса A из функции Func() унаследованного класса B. Те же правила действуют не только для переменных, но и для функций базового класса A.

C++. Наследование для двух классов A и B

Рисунок 2. Наследование для двух классов A и B. К private-членам базового класса доступ из унаследованного класса запрещен. К protected— и public— членам базового класса доступ разрешен

 

3.2. Взаимодействие двух классов. Доступ из экземпляра (объекта) унаследованного класса к элементам базового класса с использованием модификаторов доступа private и protected

Если рассматривать доступ из экземпляра (объекта) унаследованного класса к элементам базового класса, то отличие от предыдущего случая (пункт 3.1) заключается в использовании ключевого слова protected и способе наследования класса. Класс может быть унаследован как private, protected или public. Если класс унаследован как private, то ключевое слово private указывать не обязательно (см. рисунок 2).

На рисунке 3 изображены возможные варианты доступа к элементам базового класса из экземпляра унаследованного класса. В любом варианте наследования базового класса доступ к элементам этого класса из экземпляра производного класса запрещен.

C++. Наследование. Модификаторы доступа private, protected запрещают доступ

Рисунок 3. Модификаторы доступа private, protected запрещают доступ к элементам класса из любого экземпляра класса

 

3.3. Взаимодействие двух классов. Доступ к элементам базового класса из производного класса. Модификатор доступа public

Если в базовом классе A некий элемент объявляется с модификатором доступа public, то экземпляр унаследованного класса B:

  • имеет доступ к элементам базового класса A, если производный класс B наследует класс A с модификатором доступа public;
  • не имеет доступа к элементам базового класса A, если производный класс B наследует класс A как private— или protected-.

На рисунке 4 наглядно показаны все возможные варианты такого доступа.

C++. Наследование. Доступ к public-элементам базового классаРисунок 4. Доступ к public-элементам базового класса: 1) базовый класс унаследован как private-класс; 2) базовый класс унаследован как protected-класс; 3) базовый класс унаследован как public-класс.

 

4. Наследование 3-х и более классов. Доступ из унаследованных классов

Как было показано выше, базовый класс может быть унаследован путём указания перед его именем модификаторов private, protected, public. Отличие в использовании этих модификаторов проявляется в классе, являющемся производным от унаследованного класса. То есть, если дано три класса с именами A, B, C, последовательно наследующими друг друга, то влияние модификаторов будет именно на класс C.

 

4.1. Доступ к private-базовому классу из производных классов

На рисунке 5 изображен доступ к базовому классу A из производного класса C. Класс A в классе B наследуется как private-класс (скрытый). Это означает, что доступ к любому элементу класса A из производного класса C запрещен.

C++. Наследование. Запрещен доступ к элементам private-класса A из унаследованного класса C

Рисунок 5. Запрещен доступ к элементам private-класса A из унаследованного класса C

 

4.2. Доступ к protected— и public— базовому классу из производных классов

Если базовый класс A унаследован с модификаторами protected или public, то элементы этого класса доступны в унаследованных классах B и C.

 

C++. Наследование. Модификаторы protected и public перед именем базового класса

Рисунок 6. Модификаторы protected и public перед именем базового класса. Открытие доступа к protected— и public-элементам базового класса

 


Связанные темы