Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по Технологии разработки ПО 2005.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
833.54 Кб
Скачать

Наследование

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

Базовый класс

Производный класс

Свойства А и Б доступны

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

На одном из прошлых занятий мы разбирали класс Count, в котором использовалась перегруженная операция ++. Допустим теперь нам необходимо, не изменяя этот класс, создать метод для уменьшения счётчика. Допустим на создание и тестирование класса Count было затрачено много времени и желание его не изменять вполне очевидно. Или мы просто не имеем доступа к исходному коду класса, например, если он распространяется как часть библиотеки классов. В этих случаях целесообразно использовать наследование для создания производных классов.

class Count { //базовый класс

protected:

int c;

public:

Count( ) { c=0; }

Count(int t) { c=t; }

int get() const {

return c;

}

Count operator++() {

++c;

return Count(c);

}

};

//---------------------------------------------------------------------------

class CountPr : public Count { // производный класс

public:

Count operator--() {

--c;

return Count(c);

}

};

//---------------------------------------------------------------------------

int main( ) {

CountPr c1; // объект с1 производного класса

cout << "\n c1=" << c1.get();

++c1; ++c1; ++c1;

cout << "\n c1=" << c1.get();

--c1; --c1;

cout << "\n c1=" << c1.get();

getch(); return 0;

}

В данной программе определён новый производный класс CountPr, который включает в себя новый метод уменьшения счётчика и в тоже время наследует (использует) все возможности базового класса Count (его конструкторы и методы).

Строка class CountPr : public Count определяет, что класс CountPr является наследником базового класса. Ключевое слово public определяет, что объект производного класса может иметь доступ к методам базового класса, объявленным как public. Если используется ключевое слово private, то для объектов производного класса нет доступа к членам базового класса.

При создании объекта с1 производного класса происходит его инициализация нулевым значением несмотря на то, что в классе CountPr нет конструктора. Здесь работает принцип – если конструктор производного класса не определён, то будет использоваться подходящий конструктор базового класса. В данном случае используется конструктор без аргументов базового класса Count. Таким образом, использование доступного метода взамен отсутствующего – обычная ситуация, возникающая при наследовании. Действительно, объект с1 класса CountPr, не находя методы в своём классе, использует необходимые методы из базового класса.

Вывод программы:

С1=0

С1=3

С1=1

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

Таблица 1. Наследование и доступ

Спецификатор доступа

Доступ из самого класса

Доступ из производных классов

Доступ из внешних классов и функций

public

Есть

Есть

Есть

protected

Есть

Есть

Нет

private

Есть

Нет

Нет

Таким образом, если создаётся класс, который впоследствии будет использоваться как базовый класс при наследовании, то данные, к которым необходимо иметь доступ из производного класса, следует объявлять как protected.

Необходимо помнить, что наследование не работает в обратном направлении. Базовому классу и его объектам недоступны производные классы. То есть, если создать объект с2 класса Count, то он не сможет использовать метод operator--() класса CountPr, а объект производного класса может использовать все методы, как базового класса, так и производного.