Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
М.у. объектно-ориентир. прогр. с правкой.doc
Скачиваний:
70
Добавлен:
30.03.2015
Размер:
266.24 Кб
Скачать

Лабораторная работа 3 наследование

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

Основная форма наследования:

class имя_наследующего_класса: режим_доступа наследуемый_класс ..;

В языке C++ принято называть наследуемый класс базовым классом, наследу-ющий класс – производным классом. Режим_доступа – это одно из ключевых слов private, public или protected. Опция public означает, что все элементы типа public предка будут типа public для класса, который нас­ледует его. Общие (public) элементы могут быть доступны другим функциям программы. Приватные (private) элементы недоступны для производного класса, а доступны только функциям-членам класса или дружественным (friend) функциям. Защищенные (protected) элементы также могут быть доступны только функциям-членам класса или дружественным функциям.

Например:

class X // Базовый класс X

{ int i;

int j;

public:

void get_f(void);

void put_f(void);

};

class Y: public X // Производный класс Y

{ int m;

public:

int get_m(void);

void make_m(void);

};

Здесь Х – базовый класс, Y – производный класс. Функции-члены класса Y могут использовать общие функции get_f() и put_f(), но они не могут использовать i и j, так как они приватные для Х и, соответственно, недоступны для функций get_m(), put_m() класса Y.

Можно обеспечить доступ членов-функций класса Y к элементам i и j класса Х. Для этого в классе Х надо объявить их защищенными – protected:

class X

{ protected:

int i;

int j;

public:

void get_f(void);

void put_f(void);

};

class Y: public X

{ int m;

public:

int get_m(void);

void make_m(void);

};

Теперь члены класса Y имеют доступ к членам i, j класса Х. В то же время i, j остаются недоступными для остальной части программы. Доступ наследуется к элементам, объявленным защищенными или общими, но не наследуется для приватных элементов.

Пример. Пусть уже имеются такие классы как NAME (содержащий данные об имени человека) и JOB (членами-данными которого являются место работы чело­века и его должность) и необходимо создать класс, содержащий более полную информацию о сотруднике некоторой компании, то кроме перечисленной информации нужно включить возраст и пол. Очевидно, удобно новый класс PERSON сделать наследником уже имеющихся классов NAME и JOB.

Пример: Создадим класс «студент» и класс-наследник «преподаватель».

class Student // Описание классов

{ protected:

char name[50]; // ФИО

int age; // возраст

char sex[50]; // пол

public: Student(char n[],int a,char s[]);

public: void about(void); // Функция вывода информации

};

class Teach: public Student

{ char subject[50]; // преподаваемый предмет

public: Teach (char n[50],int a,char s[50],char su[50]);

public: void about(void);

};

//--------привычная часть программы-------

#include<stdio.h>

#include<conio.h>

#include<string.h>

//--------------class Student---------------------- //реализация функций классов

Student::Student(char n[50],int a,char s[50])

{ strcpy(name,n); age=a; strcpy(sex,s);}

void Student::about(void) //функция вывода информации

{ gotoxy(10,4); printf("ФИО : %s",name);

gotoxy(10,6); printf("Возраст : %d",age);

gotoxy(10,8); printf("Пол : %s",sex);}

//-----------------class Teach--------------(наследник Student'a)

Teach::Teach(char n[50],int a,char s[50],char su[50]): Student(n,a,s) //используем клаcc Student

{ strcpy(subject,su); } //и добавляем новый член-subject

void Teach::about(void)

{ Student::about();

gotoxy(10,10);printf("Преподаваемый предмет : %s",subject);

}

//----------------основная программа------------------------

void main()

{

Student *stud;

Teach *teacher;

clrscr();

gotoxy(26,1);

cprintf("Студент :");

stud = new Student("Петров Петр Петрович",17,"муж.");

stud ->about();

delete stud;

gotoxy(25,24);

cprintf("Нажмите же что-нибудь !");

getch();

clrscr();

gotoxy(25,1);

cprintf("Преподаватель :");

teacher = new Teach("Василий Иванович Чапаев",45," муж.","плавание");

teacher ->about();

delete teacher;

gotoxy(25,24);

cprintf("Нажмите ЛЮБУЮ клавишу для выхода");

getch();

}

Наследование позволяет передавать все определяемые пользователем свойства класса нескольким классам, наследующим данный класс. Проиллюстрируем передачу режима доступа к переменным при наследовании типа X–>Y–>z .

#include<iostream.h>

class X

{

protected:

int i;

int j;

public:

void get_f(void);

void put_f(void);

};

class Y: public X // i, j класса Х стали protected членами в классе Y

{ int m;

public:

int get_m(void);

void make_m(void);

};

class Z: public Y // Z имеет доступ к переменным i, j класса Х

{ public: // Z не имеет доступа к m класса Y

void d(void);

};

void X:: get_f(void)

{ cout << "Введите два числа:" << "\n";

cin>>i>>j;}

void X::put_f(void)

{ cout << "i=" << i << "j=" << j << "\n";}

int Y::get_m(void)

{ return m;}

void Y::make_m(void)

{ m = i*j; }

void Z::d(void)

{ i = 5; j = 4;}

void main()

{

Y a;

Z b;

a.get_f();

a.put_f();

a.make_m();

cout << a.get_m() << "\n";

b.d();

b.put_f();

b.make_m();

cout << b.get_m() << "\n";

}

Если мы заменим режим доступа при наследовании класса Х на private, то функция void Z::d(void) не будет иметь право доступа к переменным i, j.

Если же мы заменим режим доступа при наследовании класса Z на private, не изменяя режим доступа при наследовании класса Х, то действие примера по сравнению с начальным не изменится.

Базовые классы создаются в том порядке, в котором они перечислены в списке базовых классов при объявлении производного класса Z.

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

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