Практическое занятие № 12
Тема: Наследование и полиморфизм в классах.
Цель работы: получить практические навыки по созданию производных классов и виртуальных методов в этих классах.
Ход работы
1. Пусть имеется некоторый объект "Геометрическая фигура - прямоугольник". Объект описывается длиной и шириной, имеет конструктор, метод ввода новых размеров фигуры, метод вывода текущих размеров фигуры, метод расчета периметра фигуры, метод расчета площади фигуры.
Описать класс для работы с такой фигурой. При этом создать два вида конструктора: конструктор со значениями по умолчанию, конструктор с возможностью задания конкретных значений.
Класс сохранить в отдельном модуле.
Указания: опишем класс для работы с прямоугольником
//заголовок файла
модуля
#ifndef RECT_H
#define
RECT_H
#include
<iostream.h>
class rect
{
public:
//описываем свойства класса (длины сторон)
float storona1, storona2;
//первый тип конструктора с длинами по умолчанию
rect()
{
storona1=1;
storona2=1;
}
//второй тип конструктора с возможность задания длин
rect (int a, int b)
{
storona1=a;
storona2=b;
}
//метод ввода с клавиатуры длин сторон фигуры
void set_razmer()
{
cout<<"-введите
длину первой стороны: ";
cin>>storona1;
cout<<"-введите
длину второй стороны: ";
cin>>storona2;
}
//метод вывода длин сторон фигуры на экран
void show_razmer()
{
cout<<storona1<<"х"<<storona2;
}
//метод расчета периметра фигуры
float perimetr ()
{
return 2*(storona1+storona2);
}
//метод расчета площади фигуры
float ploschad ()
{
return storona1*storona2;
}
};
#endif
Сохраняем код в отдельный файл под именем rect.h
2. Написать основную программу (main.cpp), которая позволяет описать три фигуры (размеры двух первых фигур задаются при описании, размер третьей фигуры с помощью метода задания размера), выводит размеры их сторон на экран, подсчитывает и выводит площадь каждой фигуры.
Указания: создайте новый файл и введите код:
//подключаем стандартные модули
#include <iostream.h>
//подключаем модуль с классом rect
#include "rect.h"
int main()
{
system("cls");
cout<<"Работа с прямоугольниками\n";
cout<<"=================================\n";
//размеры первых двух фигур зададим при описании
//первая фигура размером 5х8, вторая - 4х6
rect f1(5,8),f2(4,6);
//размер третьей фигуры определяется конструктором по умолчанию 1х1
rect f3;
//изменим размер третьей фигуры на нужный
cout<<"Изменим размер третьей фигуры:\n";
f3.set_razmer();
//выведем размеры всех фигур на экран
cout<<"=================================\n";
cout<<"Фигуры имеют такие размеры:\n";
cout<<"-первая фигура: "; f1.show_razmer(); cout<<"\n";
cout<<"-вторая фигура: ";
f2.show_razmer(); cout<<"\n";
cout<<"-третья фигура: ";
f3.show_razmer(); cout<<"\n";
//выведем периметры всех фигур на экран
cout<<"=================================\n";
cout<<"Фигуры имеют такие периметры:\n";
cout<<"-первая фигура: "<<f1.perimetr()<<"\n";
cout<<"-вторая фигура: "<<f2.perimetr()<<"\n";
cout<<"-третья фигура: "<<f3.perimetr()<<"\n";
//выведем площади всех фигур на экран
cout<<"=================================\n";
cout<<"Фигуры имеют такие площади:\n";
cout<<"-первая фигура: "<<f1.ploschad()<<"\n";
cout<<"-вторая фигура: "<<f2.ploschad()<<"\n";
cout<<"-третья фигура: "<<f3.ploschad()<<"\n";
//пауза для просмотра
system("pause");
return 0;
}
Сохраните программу, запустите ее на выполнение и проверьте работу всех методов класса.
3. На основе класса "Прямоугольник" описать класс треугольник. При этом учесть, что у треугольника появилась третья сторона, которую также нужно определять в конструкторе. Так как у нового класса изменилось количество сторон, следовательно, в нем нужно переопределить все методы на новые.
Сохраните описанный файл в отдельный модуль.
Указания: новый класс будем создавать на основе существующего. Откройте созданный ранее модуль и скопируйте весь его текст в новый файл. В новом классе необходимо выполнить ряд изменений:
- добавить еще одно свойство (третья сторона);
- переопределить конструкторы (задание значения третьей стороны)
- переопределить метод задания размера сторон (добавить задание размера третьей стороны)
- переопределить метод вывода сторон на экран (добавить вывод третьей стороны)
- переопределить метод расчета периметра и площади (новые формулы).
Вначале укажем, что методы базового класса rect переопределяются в новом классе. Для этого откройте файл с модулем базового класса (rect.h) и вначале описания переопределяемых методов добавьте ключевое слово virtual. В нужных местах модуля внесите изменения:
//метод ввода с клавиатуры длин сторон фигуры
virtual void set_razmer()
//метод вывода длин сторон фигуры на экран
virtual void show_razmer()
//метод расчета периметра фигуры
virtual float perimetr ()
//метод расчета площади фигуры
virtual float ploschad ()
В файле нового модуля введите текст:
//заголовок модуля
#ifndef TREUG_H
#define
TREUG_H
//подключаем стандартные модули
#include <iostream.h>
#include <math.h>
//подключаем модуль с базовым классом
#include
"rect.h"
class
treug:public rect
{
public:
float storona3;
//конструктор без параметров
//добавим в него определение третьей стороны
//первые две стороны определяются с помощью конструктора из базового класса
treug(): rect()
{
storona3=1;
}
//конструктор с возможностью задания начальных значений
treug (int a, int b, int c): rect(a,b)
{
//первые две стороны определяются с помощью конструктора из базового класса
//третья сторона определяется в новом классе
storona3=c;
}
//переопределяем метод ввода новых размеров сторон
void set_razmer()
{
//две стороны вводим с помощью метода из базового класса
rect::set_razmer();
//третью сторону вводим в новом классе
cout<<"-введите
длину третьей стороны:";
cin>>storona3;
}
//переопределяем метод вывода размеров фигуры на экран
void show_razmer()
{
//две стороны выводим с помощью метода из базового класса
rect::show_razmer();
//третью сторону выводим в новом классе
cout<<"x"<<storona3;
}
//переопределяем метод расчета периметра по новой формуле
float perimetr()
{
return storona1+storona2+storona3;
}
//переопределяем метод расчета площади фигуры по формуле Герона
float ploschad()
{
//находим полупериметр
float per=(storona1+storona2+storona3)/2;
//считаем площадь треугольника по формуле Герона
return sqrt(per*(per-storona1)*(per-storona2)*(per-storona3));
}
};
#endif
Сохраните текст модуля в файл treug.h
4. В главной программе (main.cpp) добавьте описание трех треугольников разными способами. Для одной фигуры вызвать метод задания длин сторон. Вывести размеры, периметры и площади каждой из фигур.
Перейдите в файл основной программы. Вверху подключите модуль с порожденным классом treug с помощью команды:
//подключаем модуль с классом treug
#include "treug.h"
В конец программы, перед командой паузы system("pause") введите код для работы с порожденным классом:
cout<<"\nРабота с треугольниками\n";
cout<<"=================================\n";
//размеры первых двух фигур зададим при описании
//первая фигура размером 4x6x3, вторая - 3x5x4
treug t1(10,6,8),t2(3,5,4);
//размер третьей фигуры определяется конструктором по умолчанию 1х1x1
treug t3;
//изменим размер третьей фигуры на нужный
cout<<"Изменим размер третьей фигуры:\n";
t3.set_razmer();
//выведем размеры всех фигур на экран
cout<<"=================================\n";
cout<<"Фигуры имеют такие размеры:\n";
cout<<"-первая фигура: ";
t1.show_razmer(); cout<<"\n";
cout<<"-вторая фигура: ";
t2.show_razmer(); cout<<"\n";
cout<<"-третья фигура: ";
t3.show_razmer(); cout<<"\n";
//выведем периметры всех фигур на экран
cout<<"=================================\n";
cout<<"Фигуры имеют такие периметры:\n";
cout<<"-первая фигура: "<<t1.perimetr()<<"\n";
cout<<"-вторая фигура: "<<t2.perimetr()<<"\n";
cout<<"-третья фигура: "<<t3.perimetr()<<"\n";
//выведем площади всех фигур на экран
cout<<"=================================\n";
cout<<"Фигуры имеют такие площади:\n";
cout<<"-первая фигура: "<<t1.ploschad()<<"\n";
cout<<"-вторая фигура: "<<t2.ploschad()<<"\n";
cout<<"-третья фигура: "<<t3.ploschad()<<"\n";
Сохраните изменения, запустите программу на выполнение и проверьте работу методов обоих классов.
На этом примере видно, что несмотря на то, что принципы вызовов методов для треугольников не отличаются от прямоугольников, тем не менее принцип работы этих методов за счет переопределения стал другим.