
- •10.3 Операторы управления
- •10. 4 Оператор мультиветвления switch
- •10.6 Применение функции printf для форматирования
- •11.1 Графические программы
- •11.2 Построение символьного графика
- •11.4 Построение графика в графическом режиме
- •12.1 Передача данных для построения графика в MathCad
- •12.4 Указатели
- •12.5 Описание указателей
- •12.6 Указатели для массивов и строк
- •13.3 Оператор динамического выделения памяти new
- •Void main ( ) {
- •Void tab( ); };
- •Void main ( ) {
- •15.1 Класс объектов, элементы класса
- •15.2 Доступ к элементам класса
- •15.3 Вызов элементов класса
- •15.4 Конструкторы классa
- •15.5 Пример класса Tkplk
- •16.1 Наследование
- •16.2 Полиморфизм
- •16.3 О перегрузке функций и операций
- •17. 1 Среда программирования и библиотека vcl
- •17.2 Консольное приложение в Builder
- •При выполнении лабораторных работ в дисплейном классе используется
- •17.5 Вид экрана в builder
- •17.6 Работа с проектом в системе Builder
- •18.1 Редактор кода
- •18.4 Пример запроса, ввода, вывода для Win -программы
15.5 Пример класса Tkplk
#include <iostream.h >
#include <conio.h >
#include <string.h >
class Tkplk {
private: int sum;
public: int hei, wei, cvet;
char nazv[20];
void show (int kodrm) ;
void add (int kop);
Tkplk ( int , int , int ,char * ); //это прототип конструктора
//- - - - - - - - - - - - - - - -
int dzin() { // разбиваем копилку
cout<< " Broken with sum= "<<sum<<endl; return 1; }
}; // end of class - - - - - - - - - - - - - - - -
void Tkplk::show ( int kodrm) {
cout << "ris. kopilki with hei="
<< hei<<" wei= "<<wei<<" cvet="<<cvet<<endl;
cout<< " It is ";
for(int j=0; j<strlen(nazv);j++) cout<<nazv[j];
cout<<endl; if( kodrm==1) cout<< "ris. ramki"<<endl;
}
//- - - - - - - - - - - - - - - -
void Tkplk::add (int kop) {
sum +=kop; }
//- - - - - - - - - - - - - - - -
Tkplk::Tkplk ( int he=10, int we=10, int cv=10,char *nz="cat" )
{ sum=0; hei=he; wei=we;
cvet=cv;
for (int m=0; m<=strlen(nz); m++) nazv[m]=nz[m];
// <= for last symbol '\0'
}
// - - - - - - - - - - - - -
void main() {
Tkplk myKplk1, myKplk2(15,15,15,"tiger");
cout<< " myKplk1.hei="<<myKplk1.hei <<endl;
cout<< " myKplk2.hei="<<myKplk2.hei <<endl;
cout<< " strlen(myKplk2.nazv)="<<strlen (myKplk2.nazv);
cout<<endl;
myKplk1.show(1); myKplk2.show(0);
cout<<"end show"<<endl;
myKplk2.add(50); myKplk2.add(30);
myKplk1. dzin(); // cout<<myKplk1.sum;
myKplk2.dzin(); getch();
}
// - - - - - - - - - - --
15.6 Заключение к лекции 15
1. Класс содержит данные, методы и конструкторы, причем любая часть или любая пара
из этих трех частей может отсутствовать.
2. Обычно методы, т.е. принадлежащие классу функции, записываются вне
определения класса с указанием полного имени
тип_функц класс : : функц ( аргументы) { . . . текст функции . . . }
В этом случае наличие прототипа функции внутри определения класса обязательно.
Это правило относится и к конструкторам класса.
3. Для работы с элементами класса должны быть созданы объект или объекты
этого класса. Обращение к элементу записывается с именем объекта или с указателем
на объект.
Лекция 16 Наследование и полиморфизм
Эти принципы ООП уже рассматривались кратко в разделе 14.3. Повторим их и рассмотрим примеры использования.
16.1 Наследование
В больших программах часто возникает необходимость создания нового класса, который лишь немногими данными или функциями отличается от уже разработанного класса. Можно поступить следующим образом: переписать весь текст класса, дав ему новое имя, и затем внести в него необходимые исправления и дополнения. Но если изменений немного, то такой путь нерационален, так как приходится повторять много одинаковых операторов, что существенно удлиняет программу и затрудняет понимание её логики.
Н а с л е д о в а н и е - это использование классов-родителей (предков) для создания
классов-потомков. Эти классы называют также базовым и производным.
Создав какой-либо класс, можно создавать его модифицированные версии,
которые наследуют данные и методы класса - предка. При этом повторно используемые данные и методы можно в производном классе не описывать, что сокращает объем программы.
В С++ каждый класс может иметь сколько угодно потомков и родителей.
Связи классов представляются в виде иерархической структуры - дерева, похожего на деревья родословных (см. рис. 14.3 лекции 14). Возможна здесь и другая терминология:
класс-родитель = базовый класс = надкласс = суперкласс;
класс-потомок = производный класс = подкласс = субкласс.
Далее будем использовать термины: базовый и производный классы.
Пример заголовка для производного класса:
class circle : public figure
{ . . . дополнительные операторы нового класса . . . } ;
Двоеточие в заголовке класса разделяет производный и базовые классы. Перед именем базового класса обычно указывается модификатор доступа, который изменяет доступ в базовом классе, т.е. определяет правила наследования.
Если его нет, то по умолчанию все унаследованные элементы получают доступ private .
Появление слов public или protected означает, что доступ изменён. Существуют сложные правила о результатах сочетания двух модификаторов: доступа к элементам в базовом классе и доступа в заголовке производного класса, но рассматривать их не будем (см. [Подбельский], c.341).
Проиллюстрируем применение наследования в программе для задачи с фигурой, прямоугольником и овалом из раздела 14.1. Для упрощения овал заменим кругом, что позволит легко вычислять площади обеих фигур.
Ради компактности программы резко уменьшим количество данных в классах фигура, прямоугольник, круг по сравнению с реальными задачами: оставим только два значения ( x, y) , определяющие размер фигуры. Для размеров x, y всех фигур выберем тип double (двойная точность), который характерен в С++ для представления вещественных чисел внутри ЭВМ. Напомним, что каждое значение типа double требует для хранения 8 байтов в отличие от 4 байтов для float.
Количество методов в классах также будет мало. Каждая фигура будет «уметь» лишь устанавливать свои размеры ( функция setdim ) и показывать свою площадь при этих размерах ( функция area ).
Выберем имена для классов: figure, rectangle, circle.
Класс figure будет базовым, а два других класса производными от него в соответствии с рис. 13.2 лекции 13.
В добавление к модификаторам private, public из раздела 15.2 потребуется третий модификатор – protected ( означает защищенный), который разрешает доступ «наследникам» к собственным элементам базового класса, т.е. к private – данным.
Все методы базового класса объявим как общедоступные (public).
// d:\Proba\ lect16 _area.cpp **** 27.9.2003
#include <iostream.h>
#include <conio.h>
class figure {
protected: double x, y;
public: void setdim (double , double ) ;
virtual void area( ) { cout<< "Unknown area here!!!!!!\n"; }
};
void figure : : setdim (double i, double j=0) {
x = i; y = j; }
// **** new class - - - - - - - - - - - - - - - - - -
class rectangle : public figure {
public:
void area ( )
{ cout<<" Rectangle with x= "<< x << " y= "<<y;
cout<<" Its area= " << x * y << endl; }
};
// **** new class - - - - - - - - - - - - - - - - - -
class circle : public figure {
public:
void area ( ) {
cout<<" Circle with x= " << x ;
cout<<" Its area = " << 3.141593 * x * x <<endl; }
} ;
// - - - - - - - - - - - - - - - - - -
void main ( ) {
figure f, *p ;
rectangle r1; circle c1;
p=&f; p-> setdim(1, 2.); p -> area ( ) ;
p=&r1; p-> setdim(5, 6.); p -> area ( ) ;
p=&c1; p-> setdim(7, 8); p -> area ( ) ;
p=&c1; p-> setdim( 7 ); p -> area ( ) ;
r1.setdim (9, 9.); r1.area ( );
с1.setdim (1, 0.); c1.area ( );
getch( ); }
В производных классах для прямоугольника и круга нам не нужно повторно описывать данные и функцию setdim, но потребуется изменить функцию area. Функция area во всех классах будет разной из-за изменения алгоритма вычисления площади каждой фигуры. Это одно из проявлений полиморфизма ( см. ниже): одинаковые имена, но разные алгоритмы.
Используем новое слово - virtual - для функции базового класса.
Virtual =фактический. Оно показывает, что в производном классе эта функция может быть изменена без изменения ее заголовка. Классы rectangle и circle являются производными от класса figure, что и показано в их заголовке. Производный класс может использовать лишь общедоступные (public) и защищенные (protected) элементы базового класса.
В подпрограмме main создаются три разных объекта и один указатель, который используется для обращения к элементам этих объектам. Даны также обращения с именами объектов. Приведем результат работы программы, полученный в окне вывода:
Unknown area here!!!!!!
Rectangle with x=5 y=6 Its area = 30
Circle with x=7 Its area = 153.938
Circle with x=7 Its area = 153.938
Rectangle with x=9 y=9 Its area = 81
Circle with x=1 Its area = 3.14159