Лекция 9. ООП. Наследование
Наследование
- Позволяет описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью.
- Класс, от которого производится наследование, называется базовым, родительским или суперклассом.
- Новый класс — потомком, наследником, дочерним или производным классом.
- Позволяет использовать полиморфизм.
Is-a relationship
- «Является объектом типа» — при
public-наследовании объект производного класса является также и объектом базового класса. - Возможность манипулирования объектами по ссылкам/указателям на базовые классы.
Наследник
- Хранит в себе родителя (физически содержит подобъект базового класса).
- Сохраняет методы родителя (за исключением некоторых случаев с переопределением).
- Возможно приведение к базовому классу (slicing — при копировании по значению теряется «лишняя» часть наследника).
- Учитывает модификаторы доступа при наследовании.
Порядок вызова конструкторов и деструкторов
- Base constructor — конструктор базового класса.
- Derived constructor — конструктор производного класса.
- Derived destructor — деструктор производного класса.
- Base destructor — деструктор базового класса.
То есть деструкторы вызываются в обратном порядке относительно конструкторов.
Спецификаторы наследования
| Specifier | Within Same Class | In Derived Class | Outside the Class |
|---|---|---|---|
| Private | Yes | No | No |
| Protected | Yes | Yes | No |
| Public | Yes | Yes | Yes |
При наследовании:
publicнаследование — public → public, protected → protected.protectedнаследование — public → protected, protected → protected.privateнаследование — public → private, protected → private.
Устройство в памяти
- Выравнивание такое же, как и в структурах.
- Сначала располагаются поля базовых классов, а потом наследуемых.
Опасные ситуации
- Не всегда логика внешнего мира применима вполне к ООП (что-то может не выполняться — классический пример с прямоугольником и квадратом, нарушающий принцип LSP).
Множественное наследование
Если классу достаётся 2 метода или переменные одного наименования при множественном наследовании:
- Можно явно указать используемую переменную/функцию через
BaseClass::method(). - Можно создать ещё один метод с таким же именем и внутри вызывать тот, который нужно, из базовых (возможно, с дополнительными действиями).
Ключевое слово final у класса
- Говорит о том, что наследование запрещено.
- Пример: нет виртуального деструктора → удобно сделать
final, чтобы предотвратить наследование.
class MyClass final { /* ... */ };