Объекты в турбо ПаскалеРефераты >> Программирование и компьютеры >> Объекты в турбо Паскале
2. Создание объектов
В Турбо Паскале для создания объектов используется три зарезервированных слова: object, constructor, destructor и три стандартные директивы: private, public и virtual.
Зарезервированное слово object используется для описания объекта. Описание объекта должно помещаться в разделе описания типов:
type
MyObject = object
{поля объекта}
{методы объекта}
end;
Если объект порождается от какого-либо родителя, имя родителя указывается в круглых скобках сразу за словом object:
type
MyDescendantObject = object (MyObject)
end;
Любой объект может иметь сколько угодно потомков, но только одного родителя, что позволяет создавать иерархические деревья наследования объектов.
Для примерка создадим объект-родитель TGraphObject, в рамках которого инкапсулированы поля и методы, общие для всех остальных объектов:
type
TGraphObj = object
Private {поля объекта будут скрыты от пользователя}
X,Y: Integer;
Color: Word; {цвет фигуры}
Public
Constructor Init (aX, aY: Integer; aColor: Word);
{создаёт экзепляр объекта}
Procedure Draw (aColor: Word); Virtual;
{вычерчивает объект заданным цветом aColor}
Procedure Show;
{показывает объект – вычерчивает его цветом Color}
Procedure Hide;
{прячет объект – вычерчивает его цветом фона}
Procedure MoveTo (dX, dY: Integer);
{перемещает объект в точку с координатами X+dX и Y+dY}
end; {конец описания объекта TGraphObj}
В дальнейшем предполагается создать объекты-потомки от TGraphObject, реализующие все специфические свойства точки, линии, окружности и прямоугольника. Каждый из этих графических объектов будет характеризоваться положением на экране (поля X и Y) и цветом (поле Color). С помощью метода Draw он будет способен отображать себя на экране, а с помощью свойств “показать себя” (метод Show) и “спрятать себя” (метод Hide) сможет перемещаться по экрану (метод MoveTo). Учитывая общность свойств графических объектов, мы объявляем абстрактный объект TGraphObj, который не связан с конкретной графической фигурой. Он объединяет в себе все общие поля и методы реальных фигур и будет служить родителем для других объектов.
Директива Private в описании объекта открывает секцию описания скрытых полей и методов. Перечисленные в этой секции элементы объекта “не видны” программисту, если этот объект он получил в рамках библиотечного TPU-модуля. Скрываются обычно те поля и методы, к которым программист (в его же интересах!) не должен иметь непосредственного доступа. В данном примере он не может произвольно менять координаты реперной точки (X,Y), т.к. это не приведёт к перемещению объекта. Для изменения полей X и Y предусмотрены входящие в состав объекта методы Init и MoveTo. Скрытые поля и методы доступны в рамках той программной единицы (программы или модуля), где описан соответствующий объект. В дальнейшем предполагается, что программа будет использовать модуль GraphObj с описанием объектов. Скрытые поля будут доступны в модуле GraphObj, но недоступны в использующей его основной программе. Разумеется, в рамках реальной задачи создание скрытых элементов объекта вовсе необязательно. В объект TGraphObj они введены лишь для иллюстрации возможностей ООП.
Директива public отменяет действие директивы private, по этому все следующие за public элементы объекта доступны в любой программной единице. Директивы private и public могут произвольным образом чередоваться в пределах одного объекта.
Варианты объявления объекта TGraphObj без использования механизма private .public:
type
TGraphObj = object
X,Y: Integer;
Color: Word;
Constructor Init (aX,aY: Integer; aColor: Word);
Procedure Draw (aColor: Word); Virtual;
Procedure Show;
Procedure Hide;
Procedure MoveTo (dX,dY: Integer);
end;
Описания полей ничем не отличаются от описания обычных переменных. Полями могут быть любые структуры данных, в том числе и другие объекты. Используемые в данном примере поля X и Y содержат координату реперной (характерной) точки неграфического объекта, а поле Color — его цвет. Реперная точка характеризует текущее положение графической фигуры на экране и, в принципе, может быть любой её точкой (в данном примере она совпадает с координатами точки в описываемом ниже объекте TPoint, с центром окружности в объекте TСircle, первым концом прямой в объекте TLine и с левым верхним углом прямоугольника в объекте TRect).
Для описания методов в ООП используются традиционные для Паскаля процедуры и функции, а так же особый вид процедур — конструкторы и деструкторы. Конструкторы предназначены для создания конкретного экземпляра объекта, ведь объект — это тип данных, т.е. “шаблон”, по которому можно создать сколько угодно рабочих экземпляров данных объектного типа (типа TGraphObj, например).
Зарезервированное слово constructor, используемое в заголовке конструктора вместо procedure, предписывает компилятору создать особый код пролога, с помощью которого настраивается так называемая таблица виртуальных методов (см. ниже). Если в объекте нет виртуальных методов, в нём может не быть ни одного конструктора, наоборот, если хотя бы один метод описан как виртуальный (с последующим словом Virtual, см метод Draw), в состав объекта должен входить хотя бы один конструктор и бращение к конструктору должно прежшествовать обращению к любому виртуальному методу.
Типичное действие, реализуемое конструктором, состоит в наполнении объектных полей конкретными значениями. Следует заметить, что разные экземпляры одного и того же объекта отличаются друг от друга только содержимым объектных полей, в то время как каждый из них использует одни и те же объектные методы. В данном примере конструктор Init объекта TGraphObj получает все необходимые для полного определения экземпляра данные через параметры обращения aX, aY, aColor.
Процедура Draw предназначена для вычерчивания графического объекта. Эта процедура будет реализовываться в потомках объекта TGraphObj по-разному. Например, для визуализации точки следует вызвать процедуру PutPixel, для вычерчивания линии — процедуру Line и т.д. В объекте TGraphObj процедура Draw определена как виртуальная (“воображаемая”). Абстрактный объект TGraphObj не предназначен для вывода на экран, однако наличие процедуры Draw в этом объекте говорит о том, что любой потомок TGraphObj должен иметь собственный метод Draw, с помощью которого он может показать себя на экране.
При трансляции объекта, содержащего виртуальные методы, создаётся так называемая таблица виртуальных методов (ТВМ), количество элементов которой равно количеству виртуальных методов объекта. В этой таблице будут храниться адреса точек входа в каждый виртуальный метод. В данном примере ТВМ объекта TGraphObj хранит единственный элемент — адрес метода Draw. Первоначально элементы ТВМ не содержат конкретных адресов. Если бы мы создали экземпляр объекта TGraphObj с помощью вызова его конструктора Init, код пролога конструктора поместил бы в ТВМ нужный адрес родительского метода Draw. Далее я создам несколько потомков объекта TGraphObj. Каждый из них будет иметь собственный конструктор, с помощью которого ТВМ каждого потомка настраивается так, чтобы её единственный элемент содержал адрес нужного метода Draw. Такая процедура называется поздним связыванием объекта. Позднее связывание позволяет методям родителя обращаться к виртуальным методам своих потомков и использовать их для реализации специфичных для потомков действий.