Различные классы (а соответственно, и объекты) могут находиться в отношении наследования, при котором формируется иерархия классов, которая позволяет определять новые классы на основе уже имеющихся. Наследование – это способ повторного использования программного обеспечения, при котором новые классы создаются на основе уже существующих классов путем заимствования их атрибутов (данных) и функций (методов) и обогащения другими возможностями новых классов.
При создании нового класса вместо написания полностью новых данных-элементов и функций-элементов программист может указать, что новый класс является наследником данных-элементов и функций-элементов ранее определенного базового класса. Этот новый класс называется производным классом. Каждый производный класс сам является кандидатом на роль базового класса для будущих производных классов. При простом наследовании класс порождается одним базовым классом. При множественном наследовании производный класс наследует нескольким базовым классам (возможно, неродственным). Для описания базовых и производных классов можно также использовать struct, но нельзя union.
Производный класс обычно добавляет свои собственные данные-элементы и функции-элементы, так что производный класс в общем случае шире своего базового класса. Производный класс более специфичен по своему назначению, более узок, чем его базовый класс, и представляет меньшую группу объектов.
Каждый объект производного класса может выступать в роли объекта соответствующего базового класса. Обратное неверно. Объект базового класса не может заменять объекты классов, порожденных этим базовым классом.
Наследование формирует древовидные иерархические структуры. Базовый класс находится в иерархических отношениях со своими производными классами. Класс может существовать сам по себе, но когда класс используется в механизме наследования, этот класс становится либо базовым классом, который снабжает атрибутами и функциями другие классы, либо производным классом, который наследует эти атрибуты и функции.
Базовый класс может быть прямым или косвенным базовым классом производного класса. Прямой базовый класс явно перечисляется в заголовке при объявлении производного класса. Косвенный базовый класс явно не перечисляется в заголовке производного класса, он наследуется через два или более уровней иерархии классов.
Открытые (public) элементы базового класса доступны всем функциям программы. Закрытые (private) элементы базового класса доступны только функциям-элементам и друзьям базового класса.
Защищенный уровень доступа (protected) служит промежуточным уровнем защиты между открытым доступом и закрытым доступом. Защищенные элементы базового класса могут быть доступны только элементам и друзьям базового класса и элементам и друзьям производных классов.
Элементы производного класса могут ссылаться на открытые и защищенные элементы базового класса простым использованием имен этих элементов.
При описании класса в его заголовке перечисляются все классы, являющиеся для него базовыми. Возможность обращения к унаследованным элементам этих классов регулируется с помощью ключей (тип наследования) private, protected и public:
class имя_производн_класса:[private|protected|
public] базовый_класс
{ тело производного класса };
Если базовых классов несколько, они перечисляются через запятую. Ключ наследования должен стоять перед каждым классом, например,
class A {…};
class B {…};
class C {…};
class D: A, protected B, public C {…};
По умолчанию для классов используется ключ наследования private, а для структур – public.
Защищенное и закрытое наследование встречаются редко, и каждое из них нужно использовать с большой осторожностью.
При порождении класса с ключом наследования public открытые элементы базового класса становятся открытыми элементами производного класса, а защищённые элементы базового класса становятся защищёнными элементами производного класса. Закрытые элементы базового класса никогда не будут доступными в производном классе.
Сформулируем доступ к элементам базового класса из производного класса, основывающийся на спецификаторах доступа к элементам в базовом классе и типе наследования в виде таблицы 18.1.
| Доступ в базовом классе | Тип наследования | Доступ в производном классе |
| private protected public | private (по умолчанию для class) | недоступны private private |
| private protected public | protected | недоступны protected protected |
| private protected public | public (по умолчанию для struct) | недоступны protected public |
Таблица 18.1. Доступ к элементам базового класса в производном классе
Если базовый класс наследуется с ключом private, можно выборочно сделать некоторые его элементы из раздела public доступными в производном классе, объявив их в разделе public производного класса нужно явно следующим образом указать, что соответствующие имена (компонентов) относятся к пространству имен базового класса:
public: using имя_базы::имя_компонента;
Например,
class Base {
…
public: void f1();
};
class Derived: private Base {
…
public: using Base::f1;
};
При наследовании:
· производный класс беспрепятственно обращается к доступным для него полям данных и методам базового класса;
· базовый класс не имеет доступа к полям данных и методам производного класса;
· в объект производного класса включаются поля данных базового класса, т.е. можно считать, что в объект производного класса входит экземпляр объекта базового класса;
· если в производном классе имя поля данных или метода базового класса использовано для других целей, то соответствующий компонент базового класса доступен в производном классе с помощью операции указания области видимости:






