- •Объектно-ориентированное программирование.
- •Методические указания к лабораторным работам Омск 2007
- •Лабораторная работа 1
- •Задания к лабораторной работе 1
- •Лабораторная работа 2 конструкторы и деструкторы
- •Задания к лабораторной работе 2
- •Лабораторная работа 3 наследование
- •Задания к лабораторной работе 3
- •Лабораторная работа 4 полиморфизм. Перегрузка операций и функций
- •Задания к лабораторной работе 4
- •Лабораторная работа 5 дружественные функции
- •Void ff(...) тело функции .
- •Задания к лабораторной работе 5
- •Библиографический список
- •Содержание
Лабораторная работа 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.
Использование конструкторов при наследовании имеет свои особенности. Пока конструкторы базового классов не имеют аргументов, то производный класс может не иметь функцию-конструктор. Если же конструктор базового класса имеет один или несколько аргументов, каждый производный класс обязан иметь конструктор. Чтобы передать аргументы в базовый класс, нужно определить их после объявления конструктора базового класса.
В задании на программирование требуется определить классы и построить для них иерархию, а также продемонстрировать использование введенных конструкции при работе.