методов объекта, которые разрешено изменять в его наследниках. Изменение метода в наследниках называют переопределением метода. Итак, слово VIRTUAL указывает компилятору, что в наследниках методы включения и отключения прибора могут быть изменены в соответствии с особенностями этих наследников. К примеру, лампочка и телевизор включаются по-разному.

Основав абстрактный электроприбор, построим на нём прибор «чисто конкретный», например, телевизор.

type Телевизор = object (Электроприбор)

      procedure Включить; virtual;

      procedure Отключить; virtual;

      procedure Выбрать_канал;

      procedure Настроить_громкость;

      procedure Настроить_яркость;

      end;

Поскольку телевизор порожден от электроприбора, название его предка – «электроприбор» – указано в скобках за ключевым словом OBJECT. Наследник обязан помнить о предке, ссылаться на него, иначе не получит своего наследства – полей и методов. Виртуальные методы включить и отключить объявлены в наследнике точно так же, но будут реализованы иначе. К ним добавлены ещё три метода, характерные именно для телевизора. Схожим образом строятся и другие «конкретные» электроприборы. В результате сформируется иерархия родственных объектов, показанная на рис. 153.

Рис.153 – Иерархия электрических приборов Гражданское строительство

Но все это лишь присказка, теперь испытаем наследование и полиморфизм в деле. Создадим на базе спроектированного ранее объекта TPerson (человек) два новых типа данных: военнослужащий (TMilitary) и гражданский чиновник (TCivil), иерархия этих типов изображена на рис. 154. Эти новые типы «людей» будут содержать дополнительные поля с характерной для наследников информацией. Вдобавок изменим конструктор Init и метод Report с тем, чтобы учесть наличие новых полей. Конструктор будет содержать дополнительный параметр, а процедура распечатки – выводить на экран ещё одно поле объекта.

Рис.154 – Иерархия «человеческих» типов

Объявление

Начнем с военнослужащего, чем разнится он от простых смертных? Гордым воинским званием – от рядового до маршала. Для хранения воинского звания в объекте TMilitary добавим строковое поле mRank (Rank – звание). Ясно, что при создании объекта конструктором надо указать этот элемент. Добавим ещё один параметр конструктору объекта Init – параметр aRank, и тогда заголовок конструктора в объекте TMilitary станет таким.

constructor Init(aBearing: integer; const aName, aFam, aRank : string);

В новом конструкторе больше параметров, и работать он будет, в сравнении с предком, чуть иначе. Другими словами, в наследнике он переопределен. А если так, то где же волшебное слово VIRTUAL? Его здесь нет и не должно быть, поскольку конструктор виртуален по определению.

Теперь обратимся к процедуре распечатки Report. В наследнике она, кроме прочего, должна распечатать поле воинского звания, а значит, будет переопределена. Поэтому и объявлена виртуальной, причем и в наследнике TMilitary, и в его предке TPerson. Это необходимо, поскольку лишь виртуальный метод предка может быть виртуальным у наследника: виртуальность передается по наследству. С учетом всего сказанного, объявления типов TPerson и TMilitary теперь будут такими.

      TPerson = object

      mBearing : integer; { год рождения }

      mName : string;       { имя }

      mFam : string;       { фамилия }

Вы читаете Песни о Паскале
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату