
2 семестр ФИБС / Информатика / Lecture_5
.pdf
10. НАСЛЕДОВАНИЕ.
Наследование – это одна из важных черт языков объектноориентированного программирования. Наследование реализуется возможностью объединять один класс другим во время объявления второго класса. Механизм наследования позволяет определять новые классы, на основе уже имеющихся.
Класс, на основе которого создаётся новый класс, называется базовым (родительским классом), а новый – производным (или наследником). Непосредственно базовым классом называется такой класс, который входит в список базовых классов при определении класса. Любой производный класс может стать базовым для других создаваемых классов, таким образом реализуется иерархия классов и объектов.
10.1 Одиночное и множественное наследование
Существует возможность одиночного и множественного наследования. При одиночном наследовании базовым является один класс, а при множественном – базовых классов может быть несколько.
Механизм одиночного наследования
А
В
С
Класс А является непосредственно базовым классом; В наследуется от А, С от В.
Механизм множественного наследования
А В
С
Класс С наследуется от базовых классов А и В.
10.2 Управление доступом производных классов
При наследовании важную роль играет статус доступа к компонентам класса. В иерархии класса существуют следующие соглашения о правах доступа к компонентам класса:
–собственные 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, то общие и защищённые элементы базового класса становятся защищёнными элементами в производном классе.
Режим доступа без класса Режим .доступа в производном классе
|
|
недоступен |
|
|
|
private |
|
|
|
||
|
|
|
|
|
|
|
public |
protected |
|
|
|
protected |
|
|
|||
|
|
public |
|
|
|
public |
|
|
|
||
|
|
|
|
|
|
|
protected |
|
|
|
|
|
|
|
|
||
private |
недоступен |
|
|
|
|
|
|
|
|
|
|
protected |
|
|
|
|
|
|
protected |
|
|
|
|
public |
|
|
|
|
|
|
protected |
|
|
|
|
|
Private |
|
|
|
|
|
|
|
|
|
|
private |
|
|
|
|
|
недоступен |
|
|
|
||
|
|
|
|
|
|
protected |
|
|
|
|
|
|
private |
|
|
|
|
|
|
|
|
|
|
public |
|
|
|
|
|
|
public |
|
|
|
|
|
|
|
|
|
|
|
Таким |
|
образом, |
в |
производных |
|
|
классах статус доступа компонентов класса может быть ужесточён.
#include <iostream.h> class X {
protected: int i, j; public: int get_ij (void);
int 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 ()
{
Y 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 ();
}
10.3 Конструкторы с параметрами при наследовании.
Пока конструкторы базовых классов не имеют аргументов, производный класс может не иметь функцию конструктор. Если же конструктор базового класса имеет один или несколько аргументов, каждый производный класс обязан иметь конструктор. Чтобы передать аргументы в базовый класс нужно объявить их после объявления конструктора базового класса.
Синтаксис:
Конструктор производного класса (список аргументов.): базовый класс1 (список аргументов),
…
Базовый класс п. ((список аргументов.) {…}
Список аргументов, ассоциированных с базовым классом, может состоять из констант, глобальных переменных или параметров для конструктора производного класса. Так как объект инициализируется во время выполнения программы можно в качестве параметров использовать переменные.
#include <iostream.h> class x {
protected: int x; public: x (int i) {x=i ;}
~x () {}
void put_x (int i) {x=i ;}
int get_x (void) {return x ;}
void show (void) }; class y: public x { protected: int y; public: y (int I; int j); ~y () {}
void put_y (int i) {y=i ;}
int get_y (void) {return y ;}
void show (void); }; class z: public y { protected: int z; public: z (int i; int j); ~z () {}
void make_z (void); void show (void) ;}; void x :: show (void) {cout <<x ;}
y :: y (int i, int j): x (i) {y=j ;}
void y :: show (void) {cout <<x<<y ;}
z: z (int i, int j): y (i, j) {}

void z :: make_z (void) {z= x*y ;}
void z :: show (void)
{cout << z<< “=”<<x<<”*”<<y ;} main (void)
{
z zobj (3, 5); zobj. make_z (); zobj. show (); zobj. x :: show (); zobj. y :: show (); zobj. pub_x (7); zobj. pub_y (9); zobj. make_7 (); zobj. show (); zobj. x :: show (); zobj. y :: show ();
}
В примере использована следующая схема наследования: class x → class y → class z.
Классы x и y, по сути, равноправны, но из-за реализации механизма простого наследования, класс y отличается от x числом параметра конструктора.
10.4 Множественное наследование.
Множественное наследование представляет собой наследование, при котором создание производного класса основывается на использовании непосредственных базовых классов.
Выглядит следующим образом:
class имя производного класса. [модификатор] имя_базового класса1, имя_б.азового класса2,…,n
{…};
Рассмотрим пример при множественном наследовании:
class X
class Z
class Y