Программирование в среде Турбо Паскаль (Поляков, Круглов) - страница 183

Важно помнить, что таблица виртуальных методов — одна для каждого типа, а не у каждой переменной типа «объект». Переменная лишь держит связь с таблицей своего типа, и эта связь устанавливается конструктором. В объекте может быть определено несколько конструкторов. Сами конструкторы могут быть только статическими, хотя внутри конструктора могут вызываться и виртуальные методы.

При передаче в процедуру или функцию полиморфного объекта, имеющего виртуальные методы, адреса этих методов передаются

- 284 -

через соответствующую объекту таблицу VMT. Это гарантирует, что сработают именно те методы, которые подразумевались при объявлении типа объекта. Кроме того, если объект Z наследует от объекта Y виртуальный метод, вызывающий другие методы, то последние вызовы будут относиться к методам объекта Z, а не Y. В случае статических методов все было бы наоборот (вызовы не «вернулись» бы в Z).

Мы начали этот раздел с примера полиморфной процедуры (см. рис. 13.6). Чтобы она заработала, надо сделать некоторые методы виртуальными и объявить конструкторы в объектах. Это проделано на рис. 13.7.


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

| TYPE

| >ObjPos = OBJECT

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

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

| >{ ! } CONSTRUCTOR Init(init_line,init_col: Word);

| >{ ! } PROCEDURE Print; VIRTUAL { зарезервировано }

| END;

| >CONSTRUCTOR ObjPos.Init( init_line, init_col : Word );

| BEGIN

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

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

| END;

| PROCEDURE ObjPos.Print; { пустая процедура вывода }

| BEGIN

| >Write( #7 ); { это вызовет звуковой сигнал }

| END;

| TYPE

| >ObjSym = OBJECT( ObjPos ) { объявление наследования }

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

| >{ ! }CONSTRUCTOR Init(init_line,init_col : Word;

| >init_sym : Char);

| >{!} PROCEDURE Print; VIRTUAL {метод вывода Sym }

| END;

| >CONSTRUCTOR ObjSym.Init;

| BEGIN

| >ObjPos.Init( init_line, init_col ); { задание позиции }

| >Sym := init_sym { задание значения символа }

| END;


Рис. 13.7

- 285 -

| PROCEDURE ObjSym.Print;

| >BEGIN CRT.GotoXY( Col, Line );

| > { процедура из модуля CRT }

| > Write( Sym )

| >{ вывод символа в позиции }

| END;

| >TYPE

| > ObjString=OBJECT( ObjPos )

| > SubSt : String; { поле-значение подстроки }

| > { ! }

| >CONSTRUCTOR Init(init_line,init_col: Word;

| >init_ss : String);

| >{ ! }

| >PROCEDURE Print; VIRTUAL

| >{метод вывода SubSt }

| >END; CONSTRUCTOR ObjString.Init;

| >{инициализация полей объекта }

| BEGIN

| >ObjPos.Init( init_line, init_col );

| >{задание позиции }

| > SubSt := init_ss { задание значения подстроки }