Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТЕКСТЫ для лабработы 2 / вариант №25.rtf
Скачиваний:
20
Добавлен:
14.03.2016
Размер:
392.41 Кб
Скачать

Virtual.

B.Pascal 7 & Objects/LR - 56 -

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

─────────────────────────────────────────────────────────────────

Borland Pascal поддерживает дополнительные методы с поздним

связыванием, которые называются динамическими методами. Динами-

ческие методы отличаются от виртуальных только характером их дис-

петчеризации на этапе выполнения. Во всех других отношениях дина-

мические методы считаются эквивалентными виртуальным.

Описание динамического метода эквивалентно описанию вирту-

ального метода, но описание динамического метода должно включать

в себя индекс динамического метода, который указывается непос-

редственно за ключевым словом virtual. Индекс динамического мето-

да должен быть целочисленной константой в диапазоне от 1 до

656535 И должен быть уникальным среди индексов других динамичес-

ких методов, содержащихся в объектном типе или его предках. Нап-

ример:

procedure FileOpen(var Msg: TMessage); virtual 100;

Переопределение динамического метода должно соответствовать

порядку, типа и именам параметров и точно соответствовать типу

результата функции порождающего метода. Переопределение также

должно включать в себя директиву virtual, за которой следует тот

же индекс динамического метода, который был задан в объектном ти-

пе предка.

Примечание: Подробнее о динамических методах и о раз-

нице в диспетчеризации динамических и виртуальных методов

рассказывается в Главе 22.

B.Pascal 7 & Objects/LR - 57 -

Создание экземпляров объектов

─────────────────────────────────────────────────────────────────

Экземпляр объекта создается посредством описание переменной

или константы объектного типа или путем применения стандартной

процедуры New к переменной типа указатель на объектный тип. Ре-

зультирующий объект называется экземпляром объектного типа.

var

F: TField;

Z: TZipField;

FP: PField;

ZP: PZipField;

С учетом этих описание переменных F является экземпляром

TField, а Z - экземпляром TZipField. Аналогично, после применения

New к FP и ZP, FP будет указывать на экземпляр TField, а ZP - на

экземпляр TZipField.

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

ры этого объектного типа должны инициализироваться посредством

вызова конструктора перед вызовом любого виртуального метода. Ни-

же приведен пример:

var

S: StrField;

begin

S.Init (1, 1, 25, 'Первое имя');

S.Put ('Френк');

S.Display;

...

S.Done;

end;

Если S.Init не вызывался, то вызов S.Display приведет к неу-

дачному завершению данного примера.

Присваивание экземпляра объектного типа не подразумевает

инициализации экземпляра.

Объект инициализируется кодом, генерируемым компилятором,

который выполняется между вызовом конструктора, и когда выполне-

ние фактически достигает первого оператора в блоке кода конструк-

тора.

Если экземпляр объекта не инициализируется, и проверка диа-

пазона включена (директивой {$R+}), то первый вызов виртуального

метода экземпляра объекта дает ошибку этапа выполнения. Если про-

верка диапазона выключена (директивой {$R-}), то первый виртуаль-

ного метода неинициализированного объекта может привести к неп-

редсказуемому поведению.

Правило обязательной инициализации применимо также к экземп-

B.Pascal 7 & Objects/LR - 58 -

лярам, которые являются компонентами структурных типов. Например:

var

Comment: array [1..5] of TStrField;

I: integer;

begin

for I := 1 to 5 do

Comment [I].Init (1, I + 10, 40, 'первое_имя');

.

.

.

for I := 1 to 5 do Comment [I].Done;

end;

Для динамических экземпляров инициализация, как правило,

связана с размещением, а очистка - с удалением, что достигается

благодаря расширенному синтаксису стандартных процедур New и

Dispose. Например:

var

SP: StrFieldPtr;

begin

New (SP, Init (1, 1, 25, 'первое_имя');

SP^.Put ('Френк');

SP^.Display;

.

.

.

Dispose (SP, Done);

end;

Указатель на объектный тип является совместимым по присваи-

ванию с указателем на любой родительский объектный тип, поэтому

во время выполнения программы указатель на объектный тип может

указывать на экземпляр этого типа или на экземпляр любого дочер-

него типа.

Например, указатель типа ZipFieldPtr может присваиваться

указателям типа PZipField, PNumField и PField, а во время выпол-

нения программы указатель типа PField может либо иметь значение

nil, либо указывать на экземпляр TField, TNumField или TZipField,

или на любой экземпляр дочернего по отношению к TField типа.

Эти правила совместимости указателей по присваиванию приме-

нимы также к параметрам-переменным объектного типа. Например, ме-

тоду TField.Copy могут быть переданы экземпляры типов TField,

TStrField, TNumField, TZipField или любые другие экземпляры до-

чернего от TField типа.

B.Pascal 7 & Objects/LR - 59 -

Активизация методов

─────────────────────────────────────────────────────────────────

Метод активизируется посредством оператора вызова процедуры

или функции, состоящего из десигнатора метода, за которым следует

список параметров. Такой тип вызова называется активизацией мето-

да.

десигнатор метода

│ ┌────────────────────┐

└─┬──────────────────────────────────────>│идентификатор метода├>

│ ^ └────────────────────┘

│ ┌──────────────────────┐ ┌───┐ │

└>│ ссылка на переменную ├>│ . ├────┘

└──────────────────────┘ └───┘

Ссылка на переменную задается, если десигнатор метода должен

описывать экземпляр объектного типа, а идентификатор метода дол-

жен обозначать метод этого объектного типа.

Экземпляр, обозначенный десигнатором метода, становится не-

явным фактическим параметром метода; он соответствует формальному

параметру-переменной с именем Self, который владеет объектным ти-

пом, соответствующим активизированному методу.

Для статических методов описанный тип (на этапе компиляции)

определяет, какой из методов активизируется. Например, десигнато-

ры F.Init и FP^.Init всегда активизируют TField.Init, так как

описанным типом F и FP^ является TField.

Для виртуальных методов выбором экземпляра управляет факти-

ческий тип (этапа выполнения). Например, десигнатор FP^.Display

может активизировать методы TField.Display, TStrField.Display,

TNumField.Display или TZipField.Display (в зависимости от факти-

ческого типа экземпляра, указываемого FP).

В операторе with, ссылающемся на экземпляр объектного типа,

ссылка на переменную в десигнаторе метода может опускаться. В

этом случае экземпляром, на который ссылается оператор with, ста-

новится неявный параметр Self активизации метода. Аналогично,

ссылка не переменную может опускаться в методе. В этом случае

параметром Self метода, содержащего вызов, становится неявный па-

раметр Self активизации метода.

B.Pascal 7 & Objects/LR - 60 -

Активизация уточненных методов

─────────────────────────────────────────────────────────────────

В методе, операторе вызова функции или процедуры для обозна-

чения активизации конкретного метода допускается использование

десигнатора уточненного метода. Такой тип вызова называется акти-

визацией уточненного метода.

десигнатор уточненного метода

│ ┌──────────────────────┐ ┌───┐ ┌────────────────────┐

└─┬>│ идентификатор ├>│ . ├───────>│идентификатор метода├>

│ │ объектного типа │ └───┘ ^ └────────────────────┘

│ └──────────────────────┘ │

│ ┌──────────────────────┐ │

└>│ inherited ├──────────┘

└──────────────────────┘

Объектный тип, заданный в десигнаторе уточненного метода,

должен быть таким же, как и включающий метод объектный тип, или

соответствовать родительскому типу.

Для обозначения родительского объектного типа или объектного

типа, включающего метод, можно использовать ключевое слово

Соседние файлы в папке ТЕКСТЫ для лабработы 2