Е. К. Пугачев Объектно-ориентированное программирование Под общей редакцией Ивановой Г. С. Рекомендовано Министерством общего и профессионального образования Российской Федерации в качестве учебник

Вид материалаУчебник

Содержание


2.7.Разработка программ с использованием объектно-ориентированного программирования на языке Borland Pascal 7.0
Пример 2.29. Программа «Текстовые эффекты»
На первом этапе
Второй этап
На третьем этапе
End; Procedure Cchar.Print
Procedure LinMovX.Tie
Procedure LinMovY.Move
V[1]:=pi; for i:=2 to L do V[i]:=V[i-1]+D
Var Sx1,Sx2:LinMovX; Sy1,Sy2:LinMovY; Sc1,Sc2:LinMovCir
Подобный материал:
1   ...   11   12   13   14   15   16   17   18   ...   39
^

2.7.Разработка программ с использованием объектно-ориентированного программирования на языке Borland Pascal 7.0


Поэтапно рассмотрим процесс разработки программы с использованием технологии ООП.


^ Пример 2.29. Программа «Текстовые эффекты»

Условие задачи. Разработать программу, которая создает на экране компьютера «бегущие» строки с разными траекториями движения (рис. 2.9). Предусмотреть возможность добавления новых функций управления строками без изменения ранее разработанного текста программы.



Рис. 2.42. Вид экрана при выполнении программы «Текстовые эффекты»

^ На первом этапе необходимо выполнить анализ и объектную декомпозицию предметной области задачи.

В языках программирования обычно под строкой понимают последовательность символов. Для отображения на экране «бегущих» строк со сложными траекториями движения необходимо иметь возможность управления каждым символом строки (объект Символ). Такое управление должно включать возможность создания Символов и отображения их при перемещении в соответствии с заданным законом. Для управления символами строки необходим специальный объект, который, в соответствие с отображаемым предметом, назовем Строкой (рис. 2.10). Каждая строка будет получать сообщения «Создать» и «Вывести на экран». Конкретный закон перемещения символов строки будет определяться отдельно для каждой строки при разработке соответствующего класса.



Рис. 2.43. Диаграмма объектов программы «Текстовые эффекты»

^ Второй этап включает:

а) логическое проектирование - разработку классов для реализации данной системы;

б) физическое проектирование – разбиение программы на модули.

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

1) Сколько классов требуется для реализации всех объектов, полученных при объектной декомпозиции задачи?

2) Какие данные, характеризующие состояние объекта, необходимо представить в виде полей класса?

3) Какие методы, определяющие элементы поведения объектов класса, должен содержать каждый из классов?

4) Связаны ли между собой классы данной задачи? Если связаны, то как? Можно ли построить иерархию классов, стоит ли использовать композицию, наполнение или полиморфизм?

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

Для реализации объектов типа Строка потребуется несколько классов: абстрактный базовый класс Строка, который будет содержать основные параметры строк и общие для всех типов строк методы инициализации Init и вывода OutS. Эти методы обращаются к пока неопределенным методам движения Move и связывания символов строки Tie, поэтому методы Tie и Move также объявлены в классе, но их реализация пока откладывается (абстрактные – «пустые» методы). Производные классы определяют конкретные виды движения: LinMovX – движение строки по горизонтали, LinMovY – движение строки по вертикали и LinMovCir – движение строки по окружности.

Они будут наследовать поля и методы базового класса, перекрывать абстрактные методы Move и Tie и при необходимости добавлять собственные поля (рис.2.11).



Рис. 2.44. Структура классов программы «Текстовые эффекты»

Класс Cchar включает также поле M – массив указателей на объекты типа сhar. Указатели используются исходя из того, что принципиально на базе класса Cchar можно построить другие более сложные классы, которые также могут управляться объектами класса Line и, соответственно, объектами классов, производных от Line. Из тех же соображений метод Print объявлен виртуальным.

Таким образом, при разработке классов были применены специальные средства ООП: механизмы наследования, наполнения, полиморфизма.

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

^ На третьем этапе приступаем к созданию библиотеки классов и основной программы, т.е. уточняем типы полей, разрабатываем алгоритмы методов, тестируем и отлаживаем программу.

Ниже приведен текст модуля библиотеки:

Unit Ex_2_13a;

Interface

Type

Pc=^Cchar;

Cchar = Object {класс Символ}

private

Ch:char; {символ - основное поле}

C,X,Y,Lx,Ly:integer; {цвет,координаты,размер символа}

public

Constructor Init(Chn:char;Cn,Xn,Yn:integer);

Procedure Print;virtual; {вывод символа}

End;

Type

Line=object {управляющий класс Линия}

private

M:array [1..100] of Pc;

L:byte; {количество символов - объектов}

D:real; {резервное поле - шаг перемещения}

public

Constructor Init(S:string;Cn,Xn,Yn:integer;Dn:real);

Procedure OutS; {вывод строки}

private

Procedure Tie(i:byte;var X,Y:integer); virtual; {связывание символов}

Procedure Move(i:byte);virtual; {перемещение}

End;

LinMovX=object(Line)

private

Procedure Tie(i:byte;var X,Y:integer); virtual;

Procedure Move(i:byte);virtual;

End;

LinMovY=object(Line)

private

Procedure Tie(i:byte;var X,Y:integer); virtual;

Procedure Move(i:byte);virtual;

End;

LinMovCir=object(Line)

private

Rc,Xc,Yc:integer; {радиус, координаты центра вращения}

V:array [1..100] of real; {угол смещения для каждого символа}

public

Constructor Init(S:string;Cn,Xcn,Ycn:integer;Dn:real);

private

Procedure Tie(i:byte;var X,Y:integer); virtual;

Procedure Move(i:byte);virtual;

End;

Implementation

{********** тела методов класса Cchar *************}

Uses crt, graph;

Constructor Cchar.Init;

Begin Ch:=Chn; {символ} C:=Cn; {цвет символа}

X:=Xn; Y:=Yn; {начальные координаты}

Lx:=Textwidth(Ch); Ly:=Textheight(Ch); {размеры символа}

^ End;

Procedure Cchar.Print; {вывод символа}

Begin Setcolor(C); Outtextxy(X,Y,Ch) End;

{********** тела методов класса Line *************}

Constructor Line.Init;

Var i:integer;

Begin

L:=Length(S); D:=Dn;

for i:=1 to L do

begin New(M[i],Init(S[i],Cn,Xn,Yn));

Tie(i,Xn,Yn);

end;

End;

Procedure Line.OutS;

Var i,c:integer;

Begin for i:=1 to L do begin

c:=M[i]^.C; M[i]^.C:=Getbkcolor; M[i]^.Print;

Move(i); M[i]^.C:=c; M[i]^.Print end;

End;

Procedure Line.Tie; Begin end; {абстрактный метод}

Procedure Line.Move; Begin End; {абстрактный метод}

{********** тела методов класса LinMovX ***********}

^ Procedure LinMovX.Tie;

Begin X:=M[i]^.X+M[i]^.Lx+2; Y:=M[i]^.Y end;

Procedure LinMovX.Move;

Begin

M[i]^.X:=Round(M[i]^.X+D);

if (D>0) and (M[i]^.X>GetmaxX-M[i]^.Lx) then M[i]^.X:=0 ;

if (D<0) and (M[i]^.X<0) then M[i]^.X:=GetmaxX-M[i]^.Lx;

End;

{********** тела методов класса LinMovY ***********}

Procedure LinMovY.Tie;

Begin X:=M[i]^.X+M[i]^.Lx; Y:=M[i]^.Y-M[i]^.Ly end;

^ Procedure LinMovY.Move;

Begin

M[i]^.Y:=Round(M[i]^.Y+D);

if (D>0) and (M[i]^.Y>Getmaxy-M[i]^.Ly) then M[i]^.Y:=0;

if (D<0) and (M[i]^.Y<0) then M[i]^.Y:=Getmaxy-M[i]^.Ly;

End;

{********** тела методов класса LinMovCir *********}

Constructor LinMovCir.Init;

Var i,Xn,Yn:integer;

Begin

L:=Length(S); Rc:=Round((L+1)*2*Textheight(S)/(2*pi));

D:=2*pi/(L+1); {шаг для исходной расстановки символов}

^ V[1]:=pi; for i:=2 to L do V[i]:=V[i-1]+D;

Xc:=Xcn; Yc:=Ycn;

for i:=1 to L do

begin Tie(i,Xn,Yn);

New(M[i],Init(S[i],Cn,Xn,Yn));

end;

D:=Dn; {шаг перемещения}

End;

Procedure LinMovCir.Tie;

Begin X:=Round(Rc*cos(V[i])+Xc); Y:=Round(Rc*sin(V[i])+Yc) End;

Procedure LinMovCir.Move;

Begin

V[i]:=V[i]+D;

M[i]^.X:=Round(Rc*cos(V[i])+Xc);

M[i]^.Y:=Round(Rc*sin(V[i])+Yc);

End;

End.

Текст основной программы при этом выглядит следующим образом:

Program Str_obj;

Uses Graph,Crt,Ex_2_13a; {модуль Ex_2_13a - библиотека классов}

^ Var Sx1,Sx2:LinMovX; Sy1,Sy2:LinMovY; Sc1,Sc2:LinMovCir;

a,r:integer; d:word;

Begin

Clrscr;

Write('Введите задержку: '); readln(d);

a:=Detect; Initgraph(a,r,'C:\TP\BGI');

Setbkcolor(8); Settextstyle(0,0,1);

Sx1.Init('Перемещение слева направо',9,245,215,3);

Sx2.Init('Перемещение справа налево',13,155,263,-3);

Sy1.Init('Перемещение сверху вниз',11,165,250,2);

Sy2.Init('Перемещение снизу вверх',12,300,400,-2);

Sc1.Init('Вращение по часовой стрелке',15,

GetmaxX div 2,GetmaxY div 2,0.05);

Sc2.Init('Вращение против часовой стрелки',

14,GetmaxX div 2,GetmaxY div 2,-0.05);

repeat {циклический опрос методов перемещения объектов}

Sx1.OutS; Sx2.OutS; Sy1.OutS;

Sy2.OutS; Sc1.OutS; Sc2.OutS;

Delay(d);

until Keypressed;

Closegraph;

End.

Вопросы к главе 2
        1. Как определяется класс в Borland Pascal 7.0? Назовите основные компоненты класса. Где и как они описываются?
        2. Как объявляются объекты класса? Перечислите способы инициализации полей. Для чего используется параметр Self? Когда его использование необходимо?
        3. Перечислите основные виды отношений между классами. Какими средствами языка Borland Pascal 7.0 они реализуются? Приведите примеры использования отношений композиции и наполнения.
        4. Какие виды полиморфизма реализованы в Borland Pascal 7.0? Определите, чем простой полиморфизм отличается от сложного. Перечислите три случая, когда использование сложного полиморфизма обязательно и объясните почему.
        5. Какие объекты называются динамическими, и в каких случаях они используются? Когда и как организуется контроль выделения памяти под размещение объекта и его полей?
        6. Зачем создаются библиотеки объектов, и какие средства для этого используются?
        7. Назовите основные этапы разработки программных систем с использованием ООП. Определите задачи каждого этапа.