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

| END;

| PROCEDURE ObjString.Print;

| BEGIN

| CRT.GotoXY(Col, Line); { процедура из библиотеки CRT }

| Write( SubSt ) { печать подстроки в позиции }

| END;

Рис. 13.5

ных «родственными» отношениями. Как правило, основная часть работы по написанию объектно-ориентированных программ состоит в построении именно иерархий объектов.

При наследовании полей в производных типах уже нельзя объявлять их идентификаторы, определенные в одном из прародительских типов. Однако на методы это ограничение не распространяется. Производный объект может переопределять любой из методов, наследуемый от своих прародителей. Если описание метода в производном типе вводит тот же идентификатор для метода, что и описание метода в прародительском типе, то в этом случае ко всем последующим потомкам переходит переопределенный метод (пока он не будет заново переопределен). Следует отметить, что во всех прародительских типах действуют те методы, которые были определены изначально именно для них.

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

- 279 -

<p>13.4. Присваивание объектов</p>

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

VAR

ObjPosVar : ObjPos; { переменная - позиция в тексте }

ObjSymVar : ObjSym; { переменная - символ в позиции }

то для копирования позиции, записанной в ObjSymVar, в переменную ObjPosVar достаточно выполнить присваивание

ObjPosVar := ObjSymVar;

Подобная операция заполнит поля данных в ObjPosVar значениями аналогичных полей, унаследованных ObjSymVar. Методы таким способом не присваиваются. Поскольку производный тип всегда получается не меньшим, чем прародительский, операция Присваивания возможна именно таким путем:

Прародитель <-- Наследник.

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

Переменные типа «объект» могут быть динамическими, т.е. объявляться как ссылки:

VAR

ObjPosVarPtr : ^ObjPos; { ссылка на позицию в тексте }

ObjSymVarPtr : ^ObjSym; { ссылка на символ в позиции }

После создания динамических объектов процедурой или функцией New ссылки (как разыменованные, так и сами по себе) могут присваиваться друг другу. Правила совместимости останутся теми же: корректными будут только присваивания ссылок на наследников ссылкам на прародителей:

- 280 -

ObjPosVarPtr := ObjSymVarPtr; { передача ссылки }

ObjPosVarPtr^ := ObjSymVarPtr^; { передача полей }

<p>13.5. Полиморфизм</p>

Подобно расширенным правилам присваивания, совместимость типов при передаче в процедуру или функцию параметров типа «объект» также понимается полнее. Формальному параметру типа «объект» может соответствовать фактический параметр не только этого же типа, но и типа, производного от него. Такое свойство совместимости объектов носит название полиморфизма. Практическим примером его использования могла бы стать процедура, выводящая либо строку, либо символ на экран. Несмотря на различие входных параметров (строка или символ), процедура будет одна — но она должна работать с объектами. В самом деле, ранее мы ввели объект-позицию ObjPos и производные от него типы ObjSym и ObjString. Если описать в процедуре формальный параметр как имеющий тип ObjPos, то по правилу совместимости в процедуру можно будет передавать фактические параметры других, производных от него типов, т.е. типов ObjSym и ObjString, и даже производных от них! Такая процедура приведена на рис. 13.6.

{ Считаются описанными типы ObjPos, ObjSym и ObjStr

(см. рис. 13.1, 13.4 и 13.5)

Процедура выводит полиморфный объект (строку или символ)}

| PROCEDURE PrintObj( VAR Obj : ObjPos );

| BEGIN

| Obj.Print

| END;

| VAR

| ObjSymVar : ObjSym; { экземпляр типа ObjSym }

| ObjStringVar : ObjString; { экземпляр типа ObjString }

| BEGIN { пример инициализации и вывода }

| ObjSymVar.Init( 10, 10, '*' );

| ObjStringVar.Init( 20, 20, '...ПОДСТРОКА...' );

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

Поиск

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