Объявление объектного типа, поля, методов

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

Type <имя объектного типа> = object <информационные поля> объекта (переменные)> <методы объекта (заголовки процедур и функций)> end;

Например, опишем объект, который будет представлять собой позицию на графическом экране. Нам понадобится объявить два поля (X и Y-координаты точки) и несколько методов: для инициализации объекта, получения его координат, уничтожения и т. п.

Type TLocation = object X,Y : Word; {Координаты позиции на экране} Procedure Init(InitX, InitY : Integer); {Инициализация объекта} Function GetX : Word; {Возвращает координату Х} Function GetY : Word; {Возвращает координату Y} Procedure GetCoords(Var CoordX, CoordY : Word); {Возвращает обе координаты} Procedure Done; {Уничтожает объект} End;

Как видно из примера, поля объекта описываются таким же образом, что и поля записи, а для описания методов объекта используются только заголовки процедур и функций. Само собой разумеется, что такой объект никому не нужен, поскольку не реализована его функциональность (то есть - не описаны тела процедур и функций). Тела методов всех объектов, объявленных в программе, описываются в разделе реализации процедур и функций программы (в любом месте и в любой последовательности, но обяза-тельно ниже "своего" объекта). Синтаксически реализация метода выглядит так же, как и реализация "обычной" процедуры или функции за одним исключением: перед именем метода через точку необходимо указать имя объекта, которому он принадлежит:

Procedure <Имя объекта>.<Имя метода>(<Формальные параметры>); <Раздел локальных описаний метода (процедуры)> begin <Операторная часть метода (тело процедуры)< end;

Области видимости в модели объектов Паскаль

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

Type

TLocation = object

private

X, Y : Word;

public

...

end;

и разместить это описание в модуле, то после подключения модуля к программе программист не сможет "напрямую" изменять значения этих полей (X, Y). Он будет вынужден вызывать соответствующие методы. По умолчанию поля и методы, описанные непосредственно за ключевым словом object, считаются общедоступными. Директива же public просто отменяет действие директивы private. То есть все последующие поля и методы будут общедоступными.

Директивы private и public могут использоваться в любом порядке сколько угодно раз, но принято при описании объектного типа после зарезервированного слова object объявлять общедоступные поля и методы и только затем после директивы private - приватные.

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

Если объектный тип создается "на базе" другого существующего объекта, то имя родительского типа должно быть указано в скобках после слова object при описании потомка:

Type <Потомок> = object(<Родитель>) <Добавленные поля> <Добавленные и переопределенные методы> end;

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

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

Type TPoint = object(TLocation) Clr : Byte; {Цвет} Visib : Boolean; {Видимость} Procedure Init (InitX, InitY:Word; InitColor:Byte); {Переопределяем метод инициализации - добавляем цвет} Function GetColor : Byte; {Возвращает цвет} Function IsVisib : Boolean; (Возвращает видимость} Procedure Show; {Делает видимым} Procedure Hide; {Делает невидимым} Procedure ChangeColor(NewColor : Byte); {Меняет цвет} Procedure MoveTo(NewX, NewY : Word); {Перемещает в новую позицию} Procedure Done; {Переопределяем для уничтожения объекта} end;

Теперь напишем реализацию методов:

Procedure TPoint.Init (InitX, InitY:Word; InitColor:Byte); begin X := InitX; Y := InitY; Clr := InitColor; Visib := False end;

Как видите, этот метод добавляет новую функциональность по сравнению с предыдущим. Первые две строки тела метода повторяют (причем полностью) операторную часть метода Init объекта TLocation, две следующие - новые. И хотя такой вариант переопределения метода тоже работоспособен, в данном случае его можно упростить с помощью такого механизма, как вызов метода непосредственного родителя из метода потомка. Для этого в Turbo Pascal есть специальное зарезервированное слово inherited (в переводе с английского - унаследованный), которым мы и воспользуемся:



Procedure TPoint.Init (InitX, InitY:Word; InitColor:Byte); begin inherited Init(InitX, InitY); Clr := InitColor; Visib := False end;

Как видите, этот метод добавляет новую функциональность по сравнению с предыдущим. Первые две строки тела метода повторяют (причем полностью) операторную часть метода Init объекта TLocation, две следующие - новые. И хотя такой вариант переопределения метода тоже работоспособен, в данном случае его можно упростить с помощью такого механизма, как вызов метода непосредственного родителя из метода потомка. Для этого в Turbo Pascal есть специальное зарезервированное слово inherited (в переводе с английского - унаследованный), которым мы и воспользуемся:

Procedure TPoint.Init (InitX, InitY:Word; InitColor:Byte); begin inherited Init(InitX, InitY); Clr := InitColor; Visib := False end;

Текст стал несколько короче. Это будет особенно заметно при дальнейшем наследовании. Вместо слова inherited можно указать имя объекта-родителя: TLocation.Init(InitX, InitY);

Продолжим:

Function TPoint.GetColor : Byte; begin GetColor := Clr; end; Procedure TPoint.Show; begin Graph.PutPixel(X, Y, Clr); Visib := True end; Procedure TPoint.Hide; begin Graph.PutPixel(X, Y, Graph.GetBkColor); Visib := False end; Procedure TPoint.IsVisib : Boolean; begin IsVisib := Visib end; Procedure TPoint.ChangeColor(NewColor : Byte); begin Clr := NewColor; If IsVisib then Show end; Procedure TPoint.MoveTo(NewX, NewY : Word); Var Status : Boolean; begin Status := IsVisib; Hide; X := NewX; Y := NewY; If Status then Show end; Procedure TPoint.Done; begin Hide; Clr := Graph.GetBkColor end;

Дочерний объектный тип "точка" - потомок родительского объекта "позиция" создан.

Наши рекомендации