| Sym := init_sym { задание значения символа } END;
| FUNCTION ObjSym.GetLine : Word;
| BEGIN
| GetLine := Line { метод опроса номера строки }
| END;
Рис. 13.3
- 276 -
| FUNCTION ObjSym.GetCol : Word;
| BEGIN
| GetCol := Col
| { метод опроса номера столбца }
| END;
| PROCEDURE ObjSym.Print;
| BEGIN
| CRT.GotoXY(Col,Line);
| { процедура из библиотеки CRT }
| Write( Sym ) { вывод символа в позиции }
| END;
Рис. 13.3 (окончание)
Обратите внимание на то, что в задании нового объекта использовались поля данных и два метода GetLine и GetCol, идентичные полям и методам ранее описанного объекта ObjPos. Метод Init переписан заново, а поле Sym и, по сути, метод Print просто добавлены. Можно сказать, что более сложный объект, описывающий символ в тексте, унаследовал свойства и методы объекта-позиции. Методология ООП строится как раз на построении такого ряда объектов, в котором можно было бы проследить развитие и наследование свойств от простых структур к сложным.
Синтаксически наследование выражается следующим образом. В случае определения типа объекта, как производного от уже существующего, имя прародительского объекта заключается в круглые скобки после служебного слова OBJECT:
TYPE
ИмяОбъектаНаследника = OBJECT( ИмяОбъектаПрародителя )
НовыеПоляОбъектаНаследника;
НовыеМетодыОбъектаНаследника;
END;
Пример на рис. 13.3 по правилам ООП и Турбо Паскаля должен выглядеть, как показано на рис. 13.4 (на нем не показаны, но используются определения, введенные ранее на рис. 13.1).
Тип «наследник» иногда называется производным типом, а тип, от которого производится наследование («прародитель») — прародительским типом. Таким образом, отличие объекта от записи состоит не только в объединении полей и методов «под одной крышей», но и в способности объектов к наследованию. Поля и методы прародителя могут появляться в телах методов наследника, как если бы они были объявлены явно. На рис. 13.4 это иллюстрируется методом Init, который для инициализации полей
- 277 -
| USES CRT; { в примере используется системный модуль CRT }
| {*3десь должны быть определения, введенные на рис.13.1*}
| TYPE
| ObjSym = OBJECT( ObjPos ) { объявление наследования }
| Sym : Char; { поле-значение символа }
| PROCEDURE Init(init_line, init_col : Word;
| init_sym : Char );
| PROCEDURE Print { метод вывода символа }
| END;
| PROCEDURE ObjSym.Init;
| BEGIN
| ObjPos.Init( init_line, init_col ); {задание позиции }
| Sym := init_sym { задание значения символа }
| END;
| PROCEDURE ObjSym.Print;
| BEGIN
| CRT.GotoXY(Col, Line); {процедура из библиотеки CRT}
| Write( Sym ) { вывод символа в позиции }
| END;
Рис. 13.4
Line и Col, «по наследству» перешедших к объекту ObjSym, пользуется наследуемой процедурой ObjPos.Init.
Продолжая ряд наследования, можно ввести объект, описывающий символ совместно с его цветовым атрибутом. Для этого достаточно описать объект, производный от ObjSym и добавляющий поле данных для атрибута и методы его назначения или опроса. Такой объект будет третьим уровнем наследования, если считать от базового объекта ObjPos. Но можно объявить и объект того же уровня наследования по отношению к ObjPos, что и ObjSym. Определим, к примеру, объект «подстрока» (он пригодится в последующих примерах). Для задания подстроки надо указать координаты ее начала номер строки и столбца) и само содержимое подстроки, которое содержит в себе указание на ее длину. Можно создать объект типа ObjString, описывающий подстроку, как производный от объекта-позиции (рис. 13.5).
Процесс наследования является транзитивным: если тип объекта TypeB наследуется от типа объекта TypeA, а тип TypeC наследуется от TypeB, то тип объекта TypeC также считается наследником типа TypeA. Таким образом, можно получить иерархию объектов, связан-
- 278 -
| TYPE
| ObjString = OBJECT( ObjPos )
| SubSt : String; { поле-значение подстроки }
| PROCEDURE Init( init_line, init_col:Word;
| init_ss:String );
| PROCEDURE Print { вывод SubSt в позиции }
| END;
| PROCEDURE ObjString.Init; { инициализация полей объекта }
| BEGIN
| ObjPos.Init( init_tine, init_col ); {задание позиции }