Вторник, 23.04.2024, 14:00Приветствую Вас Гость | RSS
Программирование на языке Turbo Pascal
Меню сайта
Категории раздела
/
Наш опрос
Оцените мой сайт
Всего ответов: 148
Статистика
счетчик посещений TOPIZ.RU
Форма входа

ИСПОЛЬЗОВАНИЕ ОБЪЕКТОВ


Идею инкапсуляции полей и алгоритмов можно применить не только к графическим объектам, но и ко всей программе в целом. Ничто не мешает нам создать объект-программу и «научить» его трем основным действиям: инициации (Init), выполнению основной работы (Run) и завершению (Done). На этапе инициации экран переводится в графический режим работы и создаются и отображаются графические объекты (100 экземпляров TPoint и по одному экземпляру TLine, TCircle, TRecf). На этапе Run осуществляется сканирование клавиатуры и перемещение графических объектов. Наконец, на этапе Done экран переводится в текстовый режим и завершается работа всей программы.

Назовем объект-программу именем TGraphApp и разместим его в модуле GraphApp (пока не обращайте внимание на точки, скрывающие содержательную часть модуля -позднее будет представлен его полный текст):

Unit GraphApp;

Interface

type

TGraphApp = object

Procedure Init;

Procedure Run;

Destructor Done;

end;

Implementation Procedure TGraphApp.Init;

...

end;

...

end.

В этом случае основная программа будет предельно простой:

Program Graph_0bjects;

Uses GraphApp;

var

App: TGraphApp;

begin

App.Init;

App.Run;

App.Done

end.

В ней мы создаем единственный экземпляр Арр объекта-программы TGrahpApp и обращаемся к трем его методам.

Создание экземпляра объекта ничуть не отличается от создания экземпляра переменной любого другого типа. Просто в разделе описания переменных мы указываем имя переменной и ее тип:

var

Арр: TGraphApp;

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

App.Init;

Арр.Run;

Арр.Done;

Переменные объектного типа могут быть статическими или динамическими, т.е. располагаться в сегменте данных (статические) или в куче (динамические). В последнем случае мы могли бы использовать такую программу:

Program Graph_0bjects;

Uses GraphApp;

type

PGraphApp =^TGraphApp;

var

App: PGraphApp;

begin

App := New(PGraphApp,Init)

Арр^.Run;

Арр^.Done

end;

Для инициации динамической переменной Арр используется вызов функции New. В этом случае первым параметром указывается имя типа инициируемой переменной, а вторым осуществляется вызов метода-конструктора, который, я напомню, нужен для настройки таблицы виртуальных методов. Такой прием (распределение объектов в динамической памяти с одновременной инициацией их ТВМ) характерен для техники ООП. -

Ниже приводится возможный вариант модуля GraphApp для нашей учебной программы:

Unit GraphApp;

Interface

Uses GraphObj;

const

NPoints = 100; {Количество точек}

type

{Объект-программа}

TGraphApp = object

Points: array [1..NPoints] of TPoint; {Массив точек}

Line: TLine; {Линия}

Rect: TRect; {Прямоугольник}

Circ: TCircle; {Окружность}

ActiveObj : Integer; {Активный объект}

Procedure Init; Procedure Run;

Procedure Done; Procedure ShowAll;

Procedure MoveActiveObj (dX,dY: Integer);

end;

Implementation Uses Graph, CRT;

Procedure TGraphApp.Init;

{Инициирует графический режим работы экрана . Создает и отображает NPoints экземпляров объекта TPoint, а также экземпляры объектов TLine, TCircle и TRect}

var

D,R,Err,k: Integer;

begin

{Инициируем графику}

D := Detect; {Режим автоматического определения типа графического адаптера}

InitGraph(D,R, '\tp\bgi') ; {Инициируем графический режим. Текстовая строка должна задавать путь к каталогу с графическими драйверами}

Err := GraphResult; {Проверяем успех инициации графики}

if Err<>0 then

begin

GraphErrorMsg (Err) ;

Halt

end;

{Создаем точки}

for k : = 1 to NPoints do

Points [k] .Init (Random(GetMaxX),Random(GetMaxY),Random(15)+1);

{Создаем другие объекты}

Line. Init (GetMaxX div 3, GetMaxY div 3,2*GetMaxX div 3, 2*GetMaxY div 3,LightRed);

Circ. Init (GetMaxX div 2, GetMaxY div 2, GetMaxY div 5, White);

Rect.Init(2*GetMaxX div 5,2*GetMaxY div 5 , 3*GetMaxX div 5, 3*GetMaxY div 5, Yellow);

ShowAll; {Показываем все графические объекты}

ActiveObj := 1 {Первым перемещаем прямоугольник}

end ; { TGraphApp .Init}

{-----------}

Procedure TGraphApp .Run ;

{Выбирает объект с помощью Tab и перемещает его по экрану}

var

Stop: Boolean; {Признак нажатия Esc}

const

D = 5; {Шаг смещения фигур}

begin

Stop := False;

{Цикл опроса клавиатуры}

repeat

case ReadKey of {Читаем код нажатой клавиши}

#27: Stop := True; {Нажата Esc}

#9:begin {Нажата Tab}

inc(ActiveObj);

if ActiveObj>3 then

ActiveObj := 3

end;

#0: case ReadKey of

#71:MoveActiveObj(-D,-D); {Влево и вверх}

#72:MoveActiveObj( 0,-D); {Вверх}

#73:MoveActiveObj( D,-D); {Вправо и вверх}

#75:MoveActiveObj(-D, 0); {Влево}

#77:MoveActiveObj( D, 0); {Вправо}

#79:MoveActiveObj(-D, D); {Влево и вниз}

#80:MoveActiveObj( 0, D); {Вниз}

#81:MoveActiveObj( D, D); {Вправо и вниз}

end

end;

ShowAll;

Until Stop

end; {TGraphApp. Run}

{-----------}

Destructor TGraphApp . Done ;

{Закрывает графический режим}

begin

CloseGraph

end; {TGraphApp. Done}

Procedure TGraphApp . ShowAll ;

{Показывает все графические объекты}

var

k: Integer;

begin

for k := 1 to NPoints do Points [k] . Show;

Line. Show;

Rect . Show;

Circ.Show

end;

{-----------}

Procedure TGraphApp.MoveActiveObj;

{Перемещает активный графический объект}

begin

case ActiveObj of

1: Rect.MoveTo(dX,dY);

2: Circ.MoveTo(dX,dY);

3: Line.MoveTo(dX,dY)

end

end;

end.

В реализации объекта TGraphApp используется деструктор Done. Следует иметь в виду, что в отличие от конструктора, осуществляющего настройку ТВМ, деструктор не связан с какими-то специфичными действиями: для компилятора слова destructor и procedure - синонимы. Введение в ООП деструкторов носит, в основном, стилистическую направленность - просто процедуру, разрушающую экземпляр объекта, принято называть деструктором. В реальной практике ООП с деструкторами обычно связывают процедуры, которые не только прекращают работу с объектом, но и освобождают выделенную для него динамическую память. И хотя в нашем примере деструктор Done не освобождает кучу, я решил использовать общепринятую стилистику и заодно обсудить с Вами последнее еще не рассмотренное зарезервированное слово технологии ООП.

В заключении следует сказать, что формалистика ООП в рамках реализации этой технологии в Турбо Паскале предельно проста и лаконична. Согласитесь, что введение лишь шести зарезервированных слов, из которых действительно необходимыми являются три (object, constructor и virtual), весьма небольшая плата за мощный инструмент создания современного программного обеспечения.

Поиск
Календарь
«  Апрель 2024  »
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
2930
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz