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

Область действия (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 (окончание)