Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Курсовая работа_ф_3 / Иванова Г.С. - Основы программирования

.pdf
Скачиваний:
852
Добавлен:
02.04.2015
Размер:
13.53 Mб
Скачать

10, Классы и объекты в Borland Pascal

Procedure TRoomJnit; {инициализирующий метод}

Begin

length: =1; width: =w; End;

End.

Сокрытие некоторых полей и методов класса упрощает интерфейс клас­ са, т. е. программист, использующий библиотечный класс, не получает лиш­ ней для него информации о внутренних механизмах реализации состояния и поведения объектов данного класса. Одновременно с этим программист, за­ нимающийся разработкой библиотечных классов, получает возможность вносить изменения в реализацию класса, не заботясь об изменении про­ грамм, использующих объекты данного класса.

10.4. Практикум. Создание универсальных объектов

Даже отдельные объекты, разработанные для выполнения наиболее час­ то встречающихся действий, могут существенно упростить программисту создание программных продуктов. В качестве примера такого «универсаль­ ного» объекта разработаем класс, объектами которого будут графики функ­ ций.

Пример 10.2. Разработать класс, объекты которого представляют собой окно, содержащее график функции одной переменной. Размеры окна, интер­ вал изменения аргумента, его шаг и сама функция должны задаваться основ­ ной программой (рис. 10.2).

Основные принципы построения графиков функций в программах об­ суждались в параграфе 8.6. По сравнению с программой, рассмотренной там, внесем следующие изменения. Во-первых, обеспечим возможность построе­ ния графика функции, заданной в основной программе, для чего используем параметр процедурного типа. Во-вторых, в процессе разработки методов, обеспечивающих реакции на запросы, выделим внутренние процедуры. В-третьих, координаты точек графика запишем в динамический массив, а сам график будем выводить с использованием процедуры рисования лома­ ной линии DrawPoly.

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

[хп, хк], количество точек п и параметры окна

 

х1, у 1, х2, у2, в которое выводится график. Кро-

Создать (...)

ме того, для построения графика необходимо

График

знать минимальное Fmin и максимальные Fmax

 

значения функции на заданном отрезке, мае-

Рис. 10.2. Объект График

штабы тх, т у по осям х и у, шаг изменения ар-

321

Часть 2, Объектно-ориентированное программирование

TWin_gr х1,у1,х2,у2, F, xn, xk, n, dx, Fmin, Fmax, mx, my, xm, ym, xs, ys, s

Init, Run, Fminmax, Rx, Ry

гумента dx, координаты нижней левой точки графика XS, ys (они отличаются от координат окна, так как часть окна отводится под вывод координат сетки) и т. п.

Примечание. Целесообразно в скрытых полях переРис. 10.3. Класс TWin gr менной-объекта хранить все данные, используемые более чем в одном методе, за исключением тех, которые в каж­ дом методе инициализируются заново. Последние имеет смысл объявлять локально в каждом

методе. Например, Fmin, Fmax, xs и ys используются в методах Run, Rx, Ry, поэтому мы хра­ ним их в объекте и определяем в инициализирующей процедуре. В то же время динамичес­ кий массив координат точек используется только в одном методе Run, следовательно, он объ­ является в нем локально и там же создается, инициализируется и уничтожается.

Класс должен уметь обрабатывать сообщения Создать и Построить. Со­ ответственно минимально он должен иметь два метода. Назовем их Init («Инициализировать») и Run («Выполнить»). Эти методы должны быть до­ ступны из основной программы, а потому объявлены в общедоступной сек­ ции public. Разрабатывая алгоритмы этих методов, выделим из метода Init процедуру Fminmax, которая будет рассчитывать и инициализировать макси­ мальное и минимальное значения функции на отрезке. Из метода Run выде­ лим в отдельные процедуры последовательности действий по построению сетки графика Rx - по горизонтали, Ry - по вертикали. Эти методы внутрен­ ние, их и все поля класса будем описывать в разделе описаний метода Run, так как доступ к ним из программы не планируется. Окончательная структу­ ра класса TWin_gr показана на рис. 10.3.

Ниже приведен текст модуля, содержащего описание класса TWin_gr.

Unit WinGr;

Interface

Uses crt.Graph;

Type

Fn=Function(X:real):real;

arr=array[L. 200] ofpointtype;

TWin_gr=object

public

procedure Inlt(axn,axk:real;an:Integer; aF:Fn;

axl,ayl,ax2,ay2:Integer); {инициализация объектов}

procedure Run;

{вывод графика}

private

 

xl,yl, x2, у2:Integer;

{координаты окна}

F:Fn;

{адрес функции}

n:Integer;

{количество точек}

xn, xk,

{интервал изменения аргумента}

322

10. Классы и объекты в Borland Pascal

dx, Fmin, Fmax, {шаг аргумента и экстремумы функции} тх, my:real; {масштабы по осям}

хт, ут, {размеры окна}

xs,ys:integer; {координаты нижней границы графика} s:string[10]; {рабочая строка для вывода разметки} procedure Fminmax; {определение минимума и максимума} procedure Rx; {сетка, параллельная оси ОХ}

procedure Ry; {сетка, параллельная оси 0Y} end;

Implementation

{метод инициализации полей}

Procedure TWin_gKlnit; begin

{параметры функции}

хп:=ахп;

xk:=axk;

п:=ап;

F:=aF:

{координаты окна}

х1:=ах1;

у1:=ау1;

х2:=ах2;

у2:=ау2;

{размер окна}

хт:='х2'х1+1; ут:=у2-у1+1;

dx:=(xk-xn)/n; {устанавливаем шаг графика функции} Fwmwox; {определяем минимальное и максимальное значения

функции на заданном отрезке} {определяем нижнюю левую точку графика}

xs:=60;

ys:=ym'Xs;

{определяем масштабы по х и у} mx:=(xm'XS*2J/abs(xk'XnJ ;

ту: =(ym'XS *2)/abs(FmaX'Fmin); end;

{метод определения экстремумов функции на отрезке}

Procedure TWin_gr.Fminmax; Var X, y:real;

i:integer; Begin x:=xn; y:=F(x);

323

Часть 2. Объектно-ориентированное программирование

Fmin:=y;

Fmax:-y;

for i:=2 ton do begin

x:=x+dx;

y:=F(x);

if y>Fmax then Fmax:=y; if y<Fmin then Fmin:=y;

end;

end;

{метод построения окна с графиком и координатной сеткой}

Procedure JWinjgKRun; Var x:real;

i:integer;

dinjirr:^arr; {указатель на динамический массив координат точек}

Begin

SetViewPort(xl,у1,x2,y2,true); {устанавливаем окно}

ClearViewPort;

 

{очищаем окно}

SetColor(2);

 

{устанавливаем цвет рисования}

Rectangle(0,0,x2'xJ,y2'yl);

{рисуем рамку}

SetColor(14);

{устанавливаем цвет рисования}

SetLineStyle(0,0,3);

{устанавливаем стиль линии: толщина 3}

х:=хп;

 

 

GetMem(dinjarr,2*n);

{запрашиваем память под массив координат}

for i:=J to п do

 

 

begin

 

 

dinjarr^fij,x: =round((X'Xn) *mx+xs);

dinjarr^fij.y; =round((Fmin'f(x)) ^my+ys);

x:'=x+dx;

 

 

end;

 

DrawPoly(n,dinjarr^);

{рисуем график}

FreeMemfdinjarrJ'^n);

{освобождаем память}

SetLineStyle(0,OJ); {устанавливаем стиль линии: толщина 1} Rx; {выводим сетку, параллельную оси х}

Ry; {выводим сетку, параллельную оси у} ReadKey; {ожидаем ввода любого символа}

end;

{метод вывода сетки, параллельной оси х}

Procedure TWin^gr.Rx; Var jc, dxl:real; Begin

x;=xn;

dxl:=(xk'Xn)/5;

324

10. Классы и объекты в Borland Pascal

SetColor(ll);

SetTextStyle(0,l,l); repeat

Str(x:6:3,s);

OutTextXY(round((X'Xn) *mx+xs-3),ys+5,s): Line(round((X'Xn) *mx-^xs),ym'20,round((x-xn) *mx+xs),20); x:=x+dxl;

until x>xk+0.0000001;

end;

{метод вывода сетки, параллельной оси х}

Procedure TWin_gr.Ry; Var у, dyl.real; Begin y:=Fmin;

SetTextStylefOAl);

dyl:=(fmaX'fmin)/5; repeat

Str(y:6:3.s);

OutTextXY(5, round(-(y-Fmin) "^my+ys-10),s); Line(10, round('(y'Fmin)*my^ys),

xm-10, round('(y'Fmin)*my+ys)); y:-=y+dyl;

until y>Fmax+0.0000001;

end;

End.

Разработав модуль WinGr, мы можем в любой программе построить гра­ фик. Для этого необходимо: подключить модуль WinGr, описать функцию, объявить соответствующий объект и вызвать методы Init и Run этого объек­ та.

Ниже приведен пример программы, строящей два графика с использова­ нием WinGr.

Program Gr;

Uses WinGr, Graph;

{объявление переменных}

Var

Wl,W2:TWin^_gr; dr, mode:integer;

{определение функции}

Function f(x:real) :real; far; Begin

f: =abs(cos(x *x) *x) End;

325

Часть 2. Объектно-ориентированное программирование

{основная программа}

Begin dr:=detect;

InitGraphfdnmode, ");

WLInit('0.9,0.9,I00fA0,300,400);

Wl.Run;

W2.Init(l,3,200/,320J00,600,400);

W2.Run;

End

Задания для самопроверки

Задание 1. Спроектируйте универсальный класс для реализации объекта «Кру­ говая диаграмма». Разработайте тестирующую программу.

Задание 2. Спроектируйте универсальный класс для реализации объекта «Гра­ фическая строка». Предусмотрите возможность изменения цвета символов строки и направления ее вывода: горизонтальное или вертикальное. Местоположение строки на экране задавайте координатами верхнего левого угла первого символа. Разрабо­ тайте тестирующую программу.

и . ИЕРАРХИИ КЛАССОВ

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

11.1. Наследование

Наследованием называют конструирование новых более сложных про­ изводных классов из уже имеющихся базовых посредством добавления по­ лей и методов.

При наследовании объекты класса-потомка получают возможность ис­ пользования («наследуют») поля и методы класса-родителя, что позволяет повторно не определять эти компоненты класса.

При описании класса-потомка указывают класс-родитель и дополни­ тельные, определенные только для класса-потомка, поля и методы:

Туре <имя класса-потомка> = оЬ]ес((<\\мя класса-родителя>) <описание дополнительных полей и методов класса>

end;...

Пример 11.1. Разработать класс для реа­ лизации объекта Трехмерная комната, кото­ рый должен реагировать на запрос о площади

иобъеме комнаты (рис. 11.1).

Впараграфе 10.3 уже был определен класс TRoom в модуле Room, который содержал поля для хранения длины и ширины ком-

Площадь? Г

—^

Объем?

Трехмерная

комната

к^

__ __ J

Рис. 11.1. Объект Трехмерная комната

327

Часть 2. Объектно-ориентированное программирование

TRoom

наты, метод инициализации полей и метод определе­

length, width

ния площади. Построим класс для реализации объек­

Square(), Init'()

та Трехмерная комната на базе TRoom, добавив поле

Z

для хранения высоты комнаты и метод определения

TVRoom

объема

комнаты V, который обращается к

методу

height

Square

родительского класса (рис.

11.2).

Класс

V(), NewInitO

TRoom также должен включать свой метод инициа­

 

Рис. 11.2. Иерархия

лизации

объектов для инициализации

нового поля

классов для TVRoom

height.

Разрабатываемая программа должна содержать

 

указание об использовании модуля Room, в котором описан родительский класс TRoom:

Program ex; Uses Room;

Type TVRoom = object(TRoom)

heighUreal;

{поле для хранения высоты}

function V:real;

{метод определения объема}

procedure Newlnit(lw,h:real); {инициализирующий метод} end;

Procedure TVRoom.NewInit;

Begin

 

Init(lyW);

{инициализируем наследуемые поля класса}

height:=h;

{инициализируем собственное поле класса}

End;

 

Function TVRoom. V;

Begin

 

V:=^Square*height;{обращаемся к методу базового класса}

End;

VarA:TVRoom;

 

 

Begin

 

A.NewInit(3.4.5.l2.8);

 

WriteLn(*nnoutadb комнаты = \

 

A.Square:6:2);

 

WriteLn(V6beM комнаты = ', A. V:6:2);

 

End

 

Класс TVRoom, таким образом, включает три

 

поля: length, width и height (рис. 11.3) и четыре ме­

Рис. 11.3. Поля

тода: Square, Init, Newlnit и V. Все поля и методы

доступны как из методов производного класса, так

класса TVRoom

" непосредственно из программы.

328

IL Иерархии классов

Если программа, работая с объектами класса-потомка, не использует не­ которых методов родителя, то в исполняемую программу они не включают­ ся.

Примечание. По правилам Borland Pascal у класса может быть только один родитель, но сколько угодно потомков. Поскольку каждый производный класс добавляет при наследовании свои поля и методы, в иерархии классов по мере удаления от корня дерева иерархии слож­ ность классов и соответственно обье1сгов, которые эти классы реализуют, возрастает. Одно­ временно возрастает и специализация классов. Наиболее универсальные классы, таким обра­ зом, находятся у корня дерева классов.

Операция присваивания объектов родственных классов. В Borland Pascal допустимо присваивание объектам класса-родителя значений объек­ тов класса-потомка. Обратное присваивание не разрешено, так как при его выполнении методом «поле за полем» собственные поля объекта класса-по­ томка окажутся не определенными.

Например:

VarA:TRoom; B:TVRoom;...

А:-В; {допустимо} В:-А;... {недопустимо: ошибка!}

Особенности работы с указателями на объекты родственных клас­ сов. По правилам Borland Pascal допустимо указателям на объекты классародителя присваивать адреса объектов класса-потомка. Однако при эт

указателъ на объект базового класса не обеспечивает возможности обраще­ ния к полям и методам, объявленным в производном классе (рис. 11.4).

Например:

Указатель на объект класса-родителя

Шаблон указателя на

"Невидимые** поля

объект класса-родителя

и методы объекта

 

?

?

?

Объект класса-потомка

Рис. 11.4. Обращение к полям класса потомка через указатель на объекты класса-родителя

329

Часть 2. Объектно-ориентированное программирование

VarpC: ^TRoom; {указатель на объекты базового класса} E.TVRoom;... {объект производного класса}

рС:- @Е; {присваиваем указателю на объекты базового класса ад­ рес объекта производного класса}

рС^.height: =2.7; {ошибка, указатель на объекты типа класса-родите­ ля не подозревает о существовании поля height класса TVRoom}

В этих случаях приходится явно переопределять тип указателя, исполь­ зуя имя типа указателя (см. параграф 2.5):

Туре pTVRoom^'^TVRoom;

VarpC: ^TRoom; {указатель на объекты базового класса} Е:TVRoom;... {объект производного класса}

рС:= @Е; {присваиваем указателю на объекты базового класса адрес объекта производного класса}

pTVRoom(pC)^.height:=2.7; {явно переопределяем тип указателя}

Задания для самопроверки

Задание 1. Спроектируйте класс для реализации объекта «Окно», который, по­ лучив сообщение «Изобразить», должен выводить в определенное место экрана ок­ но заданного размера и цвета. На базе класса, реализующего объект «Окно», спроек­ тируйте класс для реализации объекта «Окно с текстом». Объект должен уметь реа­ гировать на сообщение «Изобразить окно и вывести в него строку текста». Разрабо­ тайте тестирующую программу.

Задание 2. Спроектируйте на базе класса, реализующего объект «Окно с текс­ том» предыдущего задания, класс, реализующий объект «Окно с текстом, меняющее цвет». Объекты данного класса должны уметь реагировать на сообщение «Изменить цвет окна».

11.2. Композиция

Композицией называют способ конструирования классов, при котором в строящийся класс включают объекты других классов. Включение реализова­

 

 

но посредством использования объектных по­

Площадь?

Трехмерная

лей - полей типа «класс».

Объем?

Пример 11.2. Разработать класс для реа­

комната

лизации объекта Квартира, который должен

 

 

Рис. 11.5. Объект Квартира

реагировать на запрос о жилой площади квар-

тиры (рис. 11.5).

330

Соседние файлы в папке Курсовая работа_ф_3