Но в таком случае мы, во-первых, как бы «выносим» метод за границы объекта, а во-вторых, метод назначения позиции может быть гораздо более сложным (и мы это покажем позже), и в случае его изменения придется переделывать все присваивания вместо одного единственного метода. В ООП должно выполняться «джентльменское» соглашение: доступ к полям-данным объекта должны иметь только методы этого объекта. Нарушение этого правила может свести на нет все преимущества объектного подхода.

При объявлении объектов должны выполняться следующие требования:

— описание типа «объект» может производиться только в блоке определения типов TYPE основной программы или в разделах модулей; нельзя описывать локальные объекты в подпрограммах;

— при описании типа объекта все поля данных должны находиться перед описаниями методов;

– компоненты объекта не могут быть файлами, а файлы, в свою очередь, не могут содержать компоненты типа «объект».

Данные типа «объект» не могут быть записаны в файл на диске. Тем не менее в демонстрационном архиве OOP.ARC пакета Турбо Паскаль приведены две программы: OBJECTS.PAS и ODEMO.PAS, которые совместно с находящимися там же ассемблерными вставками реализуют механизм хранения объектов на диске.

<p>13.2. Область действия полей объекта и параметр Self</p>

Область действия (domain) полей данных объекта неявно распространяется на тела процедур и функций, реализующих методы этого объекта. В примере на рис. 13.1 метод Init (процедура) работает с полями Line и Col объекта типа ObjPos, обращение к которым не требует указания имени объекта. Можно сказать, что внутри методов объекта действует неявный оператор WITH. Следствием этого является то, что формальные параметры метода (если присутствуют) не могут совпадать по имени ни с одним из полей данных соответствующего объекта.

- 274 -

Мы не раз подчеркивали, что внешне объекты очень похожи на записи. Так же, как и записи, они могут явно записываться в теле оператора WITH :

VAR

ObjPosVar : ObjPos; { экземпляр объекта }

...

with ObjPosVar do { оператор присоединения }

BEGIN

Init( 1,1); { имя экземпляра опущено }

...

Init( GetLine+1, GetCol+1 );

...

end; { with }

Всякий раз, когда вызывается метод какого-либо объекта, в него, кроме фактических параметров, передается невидимый параметр Self («свой», «внутренний»). Он указывает, какому объекту принадлежит метод. Так, метод Init из примера на рис. 13.1 воспринимается компилятором так, как если бы он был описан следующим образом:

PROCEDURE ObjPos.Init( init_line, init_col : Word );

BEGIN

Self.Line := init_line; { метод задания номера строки }

Self.Col := init_col { метод задания номера столбца }

END;

Компилятор автоматически обрабатывает параметр Self, поэтому не стоит использовать его явно. Исключением является случай, когда идентификаторы начинают «конфликтовать» в пределах методов. На рис. 13.2 показано, как, используя в методе объекта параметр Self, разрешить конфликт между полями самого объекта и формального параметра (записи).

| TYPE

| PosRec = RECORD { запись }

| Line, Col : Word; { номера строки и столбца }

| END;

| ObjPos = OBJECT { объект }

| Line, Col : Word; { номера строки и столбца }

| PROCEDURE Init2( Pos : PosRec ); { метод }

| END;

Рис. 13.2

- 275 -

PROCEDURE ObjPos.Init2( Pos : PosRec );

| BEGIN

| with Pos do begin

{ присоединение для записи Pos }

| Self.Line:= Line; { Self развязывает одинаковые имена}

| Self.Col := Col

| end {with}

| END;

Рис. 13.2 (окончание)

<p>13.3. Наследование</p>

При помощи объекта типа ObjPos (см. рис. 13.1) определяется положение какого-либо символа в тексте на дисплее, но сам символ в нем не определен. Объявим объект с именем ObjSym, добавляющий символ и выполняющий определенные действия с ним (рис. 13.3).

| USES CRT; { в примере используется системный модуль CRT }

| TYPE

| ObjSym = OBJECT

| Line : Word; { номер строки с Sym }

| Col : Word; { номер столбца с Sym }

| Sym : Char; { поле-значение символа }

| PROCEDURE Init(init_line,init_col : Word;

| init_sym : Char);

| FUNCTION GetLine : Word; { опрос Line }

| FUNCTION GetCol : Word { опрос Col }

| PROCEDURE Print { вывод Sym }

| END;

| PROCEDURE ObjSym.Init; { инициализация полей объекта }

| BEGIN

| Line := init_line; { метод задания номера строки }

| Col := init_col; { метод задания номера столбца }

Перейти на страницу:

Поиск

Похожие книги