Добавил:
Помощь с лабораторными, контрольными практическими и курсовыми работами по: - Инженерной и компьютерной графике - Прикладной механике Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2 сем 1 курс С++ / Экзамен / Lektsii_Kurakina_2_semestr.pdf
Скачиваний:
12
Добавлен:
08.08.2022
Размер:
4.82 Mб
Скачать

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

6.1 Понятие наследования

Наследование – это одна из важных черт языков объектно-ориентированного программирования. Классы используются для моделирования концепций реального и программного мира. Однако ни одна концепция не существует в изоляции. Она сосуществует с родственными концепциями.

Например, концепции круга и треугольника связаны тем, что и тот, и другой являются фигурами. Концепция фигуры является общей для них. Поэтому мы должны явно определить, что классы Circle и Triangle имеют общий базовый класс Shape. Представление понятий «круг» и «треугольник» в программе без введения понятия «фигура» означало бы потерю чего-то существенного.

Отношение наследования между классами может быть представлено в графическом виде.

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

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

6.2 Базовые и производные классы

Класс, на основе которого создаётся новый класс, называется базовым (родительским классом), а новый – производным (или наследником).

Производные классы наследуют свойства базовых классов, включая данные-члены и функции-члены. Кроме того, в производном классе могут быть объявлены дополнительные данные-члены и функции-члены.

Объявление производного класса имеет следующий синтаксис:

class <имя производного класса> : <спецификатор доступа> <имя базового класса> [, <спецификатор доступа> <имя базового класса> ]

{ ... };

Если члены базового класса не переопределены в производном классе, они обозначаются и трактуются так же, как и члены производного класса. Говорят, что члены базового класса наследуются производным классом. Операция разрешения области видимости :: может употребляться для явной ссылки на член базового класса. Это обеспечивает доступ к имени, которое переопределено в производном классе.

Пример: class Base

{ public:

int a, b;

};

class Derived : public Base

{ public:

 

int b, c;

 

};

 

 

Derived d;

 

d.a

= 1;

// Инициализация a, унаследованного из класса Base

d.Base::b = 2;

// Инициализация b из класса Base

d.b

= 3;

// Инициализация b, объявленного в классе Derived

d.c

= 4;

 

Base *bp = &d;

// Преобразуем указатель на класс Derived в указатель на класс Base

6.3 Одиночное и множественное наследование

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

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

class A {

public: void f(); };

class B : public A { }; // Класс B является непосредственным базовым классом для класса

C

class C : public B // класс A – косвенным базовым классом для класса C

{ public: void f();

void ff();

};

В записи <имя класса>::<имя> имя класса определяет класс, в котором начинается поиск имени.

void C::ff()

{ f();

// Вызов функции f() из класса C

A::f(); // Вызов функции f() из класса A

B::f(); // Снова вызов функции f() из класса A, т.к. в классе В функция f() не определена

}

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

6.4 Управление доступом производных классов

При наследовании важную роль играет статус доступа к компонентам класса. В иерархии классов существуют следующие соглашения о правах доступа к компонентам класса:

собственные private элементы доступны только внутри класса, где они определены.

защищённые protected элементы доступны внутри класса и во всех производных классах.

общедоступные (открытые) public компоненты класса видимы из любой точки программы.

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

class X {

protected:

int i; j;

public: void get_ij (void);

void put_ij (void) ;};

class Y: public X {

int k;

public: int get_k (void);

void make_k (void) ;};

Функции–члены класса Y могут использовать функции get_ij, put_ij класса X, но не могут использовать ij, они не доступны для функций get_k и make_k класса Y.

Можно обеспечить доступ функции–члена класса Y к элементам класса X, описав их как protected. В тоже время ij остаются не доступными для остальной части программы.

Доступ наследуется к элементам, объявлённых защищёнными или общими, и не наследуются – для собственных private элементов.

При описании производного класса можно изменить статус доступа, наследуемым компонентам класса, с помощью модификатора статуса доступа.

Выглядит следующим образом:

class <имя производного класса> : <спецификатор доступа> <имя базового класса>

В качестве модификатора статуса доступа используются ключевые

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

Если режим доступа public, то все общие и защищённые элементы базового класса остаются общими и защищёнными элементами производного класса. Если режим доступа private, то все общие и защищённые элементы базового класса

становятся private элементами производного класса. Если режим доступа protected, то общие и защищённые элементы базового класса становятся защищёнными элементами в производном классе.

Таким образом, в производных классах статус доступа компонентов класса может быть ужесточён.

6.5 Пример

#include <iostream> using namespace std; class X {

protected: int i, j;

public: void get_ij (void); void put_ij (void);};

class Y: public X { int k;

public: int get_k (void); void make_k (void) ;}; class Z: public Y {

public: void f (void) ;}; void X :: get_ij (void)

{

cout <<”Введите 2 числа:”; cin>>i>>j;

}

void X :: put_ij (void)

{

cout <<”i=”<<i<<”j=”<<j;

}

int Y :: get_k (void) {return k ;}

void Y :: make_k (void) {k=j+i ;}

void Z :: f (void) {i=2; j=3 ;} main ()

{

Z var; Z var2; var.get_ij (); var.put_ij (); var.make_k (); cout <<var.get_k (); var2.f (); var2.put_ij (); var2.make_k (); cout <<var.get_k ();

Соседние файлы в папке Экзамен