Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекция. Объектная модель языка Free Pascal

.pdf
Скачиваний:
36
Добавлен:
18.03.2015
Размер:
494.13 Кб
Скачать

11 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

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

В FreePascal все классы являются потомками класса TObject. Поэтому если вы создаете дочерний класс прямо от класса TObject, то в определении его можно не упоминать.

Производный класс наследует от класса-предка поля и методы; если имеет место совпадение имен методов, то говорят, что они перегружаются. В зависимости от того, какие действия происходят при вызове, методы делятся на следующие группы:

Виртуальные методы.

Для них реализуется механизм позднего связывания на основе ТВМ, обеспечивая возможность построения виртуальных объектов. Самый первый виртуальный метод в иерархии описывается virtual, все же методы,

перекрывающие этот метод, описываются со спецификатором override.

Динамические методы.

Динамическими называются полиморфные виртуальные методы, доступ к которым выполняется не через ТВМ, а через специальную таблицу динамических методов (ТДМ). Такие методы описываются, соответственно, dymamic - при объявлении и override - при переопределении. В отличие от ТВМ, которая хранит адреса всех виртуальных методов данного класса, ТДМ хранит только адреса виртуальных методов, определенных в данном классе.

Использовать динамическую реализацию полиморфных виртуальных методов имеет смысл лишь в тех случаях, когда класс имеет сотни потомков, а описываемый метод вызывается крайне редко, или если метод

11

12 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

переопределяется в каждом потомке. Во всех остальных случаях лучше использовать обычную реализацию (virtual).

Абстрактные методы.

Абстрактные методы используются при объявлении методов, реализация которых откладывается. Такие методы в классе описываются служебным словом abstract и обязательно переопределяются в потомках класса.

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

Пусть нам необходимо создать новый класс TMySquare для создания объектов Квадрат. Класс TMySquare можно построить несколькими способами.

1.Класс TMySquare можно наследовать от TObject, так же как был получен класс ТМуСirсle. В этом случае нам придется повторить программирование всех методов данного класса, что явно нецелесообразно.

2.Класс TMySquare можно наследовать от TMyCircle.

Тогда мы можем наследовать от TMyCircle методы Create,

Clear, ReColor, ReSize, определяющие общие элементы поведения. Метод Draw необходимо объявить виртуальным, так как он вызывается из наследуемых методов и переопределен в классе-потомке. Метод Draw класса TMySquare должен быть объявлен переопределенным - override. Данный вариант

наследования, принципиально применимый в конкретном случае, является не универсальным (и, в общем, не логичным: как можно «наследовать» от круга квадрат?).

3. С учетом существования двух типов объектов со сходным поведением можно

13 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

создать абстрактный класс TFigure, инкапсулирующий требуемый тип поведения фигур, В этом классе нужно объявить метод Draw виртуальным

(virtual) и абстрактным (abstract) и определить методы Create, Clear,

ReColor, ReSize через метод Draw. Теперь мы можем наследовать от этого абстрактного класса классы, рисующие любые фигуры. Эти классы должны будут переопределять абстрактный метод Draw класса TMyFigure.

Unit Figure;

Interface

Type

TMyFigure=class

private

x,y,r:Word; Color: TColor; procedure Clear;

public

Construсtor Create (ax, ay, ar: Word; aColor: TColor);

Procedure Draw; virtual; abstract; {абстрактная процедура}

Procedure ReSize(ar: Word);

Procedure ReColor(acolor:TColor);

end;

TMyCircle=class(TMyFigure) {класс Окружность}

public

Procedure Draw; override; {рисование окружности}

end;

TMySquare=class(TMyFigure) {класс Квадрат}

public

13

14 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

Procedure Draw; override; {рисование квадрата}

end;

Var

MyFigure: TMyFigure;//!!!!!!не допускается!!!!!!!!

MyCircle: TMyCircle;

MySquare: TMySquare;

Implementation

Constructor TMyFigure.Create;

Begin

inherited Create;

x:=ax; y:=ay; r:=ar; Color: =aColor;

End;

Procedure TMy Figure.Clear;

Begin

End;

Procedure TMyFigure.Resize;

Begin

End;

Procedure TMyCircle.Draw;

Begin

End;

14

15 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

Procedure TMySquare.Draw;

Begin

End;

End.

4. Инкапсуляция Инкапсуляция — один из важнейших механизмов объектно-

ориентированного программирования (наряду с наследованием и полиформизмом). Класс представляет собой единство трех сущностей – полей, свойств и методов, что и является инкапсуляцией. Инкапсуляция позволяет создавать класс как нечто целостное, имеющее определённую функциональность. Например, класс TForm содержит в себе (инкапсулирует) все необходимое, чтобы создать диалоговое окно.

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

для этого служат свойства класса.

Свойство - это средство Lazarus, позволяющее определять интерфейс доступа к полям класса.

Различают:

простые или скалярные свойства;

свойства-массивы;

индексируемые свойства или свойства со спецификацией index;

процедурные свойства.

Рассмотрим только первый тип свойства - простые свойства.

15

16 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

Описание простых свойств выполняется следующим образом (квадратные скобки в данном случае указывают, что соответствующая спецификация может быть опущена):

property <имя свойства>:<тип>

[read <метод чтения или имя поля>]

[write <метод записи или имя поля>]

[stored <метод или булевское значение>]

[default <константа>];

Спецификации, начинающиеся служебными словами read и write,

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

Вместо метода чтения или записи возможно указание имени поля. Это означает, что данному свойству соответствует поле в описании класса, куда осуществляется непосредственная запись или откуда выполняется непосредственное чтение (без использования методов).

Остальные спецификации, названные спецификациями сохранения,

используются только для свойств, определяемых в секции published, т.е.

используемых для «опубликованных» компонент. Булевское значение после stored (вместо которого может быть указан метод, возвращающий булевское значение) определяет, должно ли сохраняться данное свойство компонента при сохранении формы (true - должно, false - не должно) в файле с расширением

.lfm. Последний спецификатор default определяет стандартное значение свойства, при совпадении значения поля с которым свойство не сохраняется.

Например: private

FValue: integer;

16

17 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

procedure SetValue(AValue: integer); function StoreValue: boolean;

published

property Valueinteger read FValue write SetValue stored StoreValue default 10;.. .

Данное описание определяет свойство для внутреннего поля FValue некоторого класса. Чтение свойства выполняется напрямую из поля. Для записи в поле используется специальный метод SetValue. Сохранение в форме выполняется, если метод StoreValue возвращает true и значение отлично от 10.

Принято называть поле класса, для которого определяется свойство, тем же именем, что и свойство, но с префиксом «F», а соответствующие параметры методов ввода и вывода с префиксом «А». Аналогично, имя метода чтения свойства желательно начинать с префикса «Get», метода записи - с

«Set».

При необходимости в производном классе свойство можно переопределить, изменив доступность и/или спецификации. При этом можно указывать только изменяемые спецификации: остальные - наследуются.

В программе свойства используются как обычные поля, например:

А. Value :=n;

или

k: =А.Value;

соответственно при этом будут выполняться следующие операции:

A.SetValue(n);

и

k:=A.FValue;

17

18 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

Простые свойства целесообразно использовать:

-для ограничения доступа к полю (например, доступ только для чтения);

-при необходимости обеспечить при записи или чтении выполнение некоторых дополнительных действий (например, при записи в поле необходимо еще и фиксировать факт изменения значения).

Рассмотрим пример.

Для класса TMyCircle определим два свойства Color и Radius. Изменение значений этих свойств свяжем с перерисовкой окружности. Добавим еще одно изменение: поместим вызов процедуры рисования Draw в конструктор, так как конструирование объекта обычно связано с его рисованием. Тогда получим следующее описание

Unit Circle;

Interface

Type

TMyCircle=class

private

x,y, FRadius: Word; FColor: TColor;

Procedure Clear;

Procedure Draw;

Procedure SetSize(ARadius: Word);

Procedure SetColor(AColor:TColor);

public

Constructor Create(ax,ay,ARadius: Word; AColor:TColor); property Radius:Word write SetSize;

property Color: TColor write SetColor;

18

19 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

end;

Var

MyCircle: TMyCircle;

Implementation

Constructor TMyCircle.Create;

Begin

inherited Create; x:=ax; y:=ay; FRadius: =ARadius; FColor: =AColor; Draw;

End;

Procedure TMyCircle.Draw;

Begin

End;

Procedure TMyCircle.Clear;

Begin

End;

Procedure TMyCircle.SetSize;

Begin

Clear;

FRadius:=ARadius;

19

20 Лекция 2. Объектная модель языка Free Pascal/Lazarus.

Draw;

end;

Procedure TMyCircle.SetColor;

Begin

Clear;

FColor:-AColor;

Draw;

end;

End.

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

MyCircle.Radius: =strtoint(rEdit. Text);

или

MyCircle. Color: =ColorDialog. Color;

20