Элементы ООП
Понятие объекта и его применение
Объект в Турбо Паскале – это структура данных, содержащая поля данных различных типов и заголовки методов. Метод – процедура или функция объекта.
Для описания объекта используется зарезервированное слово object:
![]()
Type MyObj = object {объект - родитель} поле1; … поле n; метод1; … метод k; end;
MyObj2= object (MyObj) {объект – потомок от MyObj} {поля}; {методы}; end;
Директива Private в описании объекта открывает секцию скрытых полей и методов. Перечисленные в этой секции элементы объекта «не видны» программисту, если этот объект он получил в рамках библиотечного tpu - модуля. Скрытые поля доступны в модуле, где описан объект. Директива Public отменяет действие директивы Private, поэтому все следующие за Public элементы доступны в любой программной единице. Директивы Private и Public могут произвольным образом чередоваться в пределах одного объекта. Для описания методов в ООП используются традиционные для Паскаля процедуры и функции, а так же особый вид процедур – конструкторы и деструкторы. Конструкторы предназначены для создания конкретного экземпляра объекта, ведь объект – это тип данных, т.е. «шаблон», по которому можно создавать сколько угодно рабочих экземпляров данных объектного типа. Типичное действие, реализуемое конструктором, состоит в наполнении объектных полей конкретными значениями. Зарезервированное слово Constructor используется вместо Procedure. Если в объекте есть хотя бы один метод, описанный как виртуальный (Vitrual – виртуальный, воображаемый. См. метод Draw– вычерчивание графического объекта), в состав объекта должен входить хотя бы один конструктор и обращение к конструктору должно предшествовать обращению к любому виртуальному методу. Деструктор Dectructor синоним Procedure. Введение в ООП деструкторов носит в основном стилистическую направленность – просто процедуру, разрушающую экземпляр объекта принято называть деструктором. Учебная задача
Разработать программу, которая создает на экране ряд графических изображений (точки – случайным образом, линия, окружность, прямоугольник) и может перемещать эти изображения по экрану.
![]()
Tab – выбор перемещаемого объекта Esc – выход из программы Перемещение с помощью стрелок: вверх, вниз, влево, вправо
- Создадим объект – родитель (GObj), в котором будут включены поля и методы общие для всех остальных объектов. Это будет абстрактный объект – не связан с конкретной графической фигурой. Каждая из графических фигур характеризуется положением на экране (поля Х и У) и цветом (поле Color). Общие методы: Конструктор Init – получает все необходимые данные для полного определения экземпляра объекта (через параметры обращения aX, aY, aColor)
- Draw – отображение объекта на экране. Виртуальный метод, т.к. каждый объект – потомок будет по-своему отображать себя на экране.
- Show – «показать себя»
- Hide – «спрятать себя»
- Moveto – перемещение по экрану
- Затем создадим объекты - потомки от GObj, реализующие все специфические свойства точки, линии, (окружности и прямоугольника – самостоятельно)
- Описание объектов поместим в модуль u_Gobj.tpu
ПРОГРАММА
- Модуль U_Gobj
- unit u_gobj;
- interface
- type
- gobj=object {объект - родитель}
- {private}
- x,y:integer; {поля}
- color:word;
- {public}
- constructor init (ax,ay:integer; acolor:word); {методы объекта}
- procedure draw(acolor:word); virtual;
- procedure show;
- procedure hide;
- procedure moveto(dx,dy:integer);
- end;
- {объект – точка. Основные действия наследует, следовательно в объекте перекрывается единственный метод Draw}
- tpoint=object(gobj)
- procedure draw(acolor:word); virtual;
- end;
- {объект – линия. Два новых поля – координаты второго конца. Дополнительные поля требуется наполнить конкретными значениями, следовательно перекрывается конструктор объекта – родителя и метод Draw}
- tline=object(gobj)
- dx,dy:integer;
- constructor init (x1,y1,x2,y2:integer; acolor:word);
- procedure draw(acolor:word); virtual;
- end;
- implementation {описание всех методов}
- uses graph;
- constructor gobj.init;
- begin
- x:=ax;
- y:=ay;
- color:=acolor;
- end;
- procedure gobj.draw;
- begin
- end;
- procedure gobj.show;
- begin
- draw(color);
- end;
- procedure gobj.hide;
- begin
- draw(getbkcolor);
- end;
- procedure gobj.moveto;
- begin
- hide;
- x:=x+dx;
- y:=y+dy;
- show;
- end;
- procedure tpoint.draw;
- begin
- putpixel(x,y,acolor);
- end;
- constructor tline.init;
- begin
- Gobj. init(x1,y1,acolor);
- dx:=x2-x1;
- dy:=y2-y1;
- end;
- procedure tline.draw;
- begin
- setcolor(acolor);
- line(x,y,x+dx,y+dy);
- end;
- end.
Использование объектов
Идею инкапсуляции полей и алгоритмов можно применять не только к графическим объектам, но и ко всей программе в целом.
Объект – программа (три основных действия):
- Init – инициализация. Экран переводится в графический режим работы и отображаются объекты (100 экземпляров Tpoint, по одному экземпляру Tline и др.)
- Run – выполнение основной программы. Осуществляется сканирование клавиатуры и перемещение графических объектов
- Done – завершение. Экран переводится в текстовый режим и завершается работа всей программы.
Gapp – имя объекта – программы, который поместим в модуль u_Gapp.tpu (см. ниже)
Основная программа будет простой:
- program gr_object;
- uses u_gapp;
- var app:gapp;
- begin
- app.init;
- app.run;
- app.done
- end.
Вариант модуля u_Gapp.tpu для нашей учебной задачи:
- unit u_gapp;
- interface
- uses u_gobj;
- const npoints=100; {количество точек}
- type gapp=object
![]()
- points:array[1..npoints] of tpoint;
- {массив точек}
- line:tline;{линия}
- actobj:integer; {активный объект}
![]()
- procedure init;
- procedure run;
- procedure done;
- procedure showall; {показывает все графические объекты}
- procedure moveactobj(dx,dy:integer);
- {перемещает активный графический объект}
- end;
- implementation
- uses graph, crt;
- procedure gapp.init;
- var gd,gm,k: integer;
- begin
- gd:=detect;
- initgraph(gd,gm,'');
- {инициализация 100 точек}
- 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,red);
- showall;
- actobj:=1; {первой перемещаем линию}
- end;
- procedure gapp.run;
- var stop: boolean; {признак нажатия Esc}
- const d=5; {шаг смещения}
- begin
- stop:=false;
- repeat {цикл опроса клавиатуры}
- case readkey of
- #27: stop:=true;
- #9: begin
- inc(actobj);
- if actobj>2 then actobj:=1
- end;
- #0: case readkey of
- #72: moveactobj(0,-d); {вверх}
- #75: moveactobj(-d,0); {влево}
- #77: moveactobj(d,0); {вправо}
- #80: moveactobj(0,d); {вниз}
- end;end;
- showall;
- until stop;
- end;
- procedure gapp.done;
- begin
- closegraph;
- end;
- procedure gapp.showall;
- var k: integer;
- begin
- for k:=1 to npoints do
- points[k].show;
- line.show;
- end;
- procedure gapp.moveactobj;
- begin
- case actobj of
- 1: line. moveto (dx,dy);
- 2: for k:=1 to npoints do points[k]. moveto (dx,dy);
- end;
- end;
- end.
Назад