Читаем Песни о Паскале полностью

Теперь то, что переехало в модуль Person, из первичного файла проекта удалим, и добавим в начале программы ссылку для импорта модуля.


USES Person;


Сохраните новую версию файла под именем «P_61_3» и убедитесь, что она компилируется без ошибок. Затем вставьте в первичный файл приведенное ранее объявление типа для наследника TMilitary. В итоге заготовка будущей программы станет такой.


{ P_61_3 – Демонстрация принципов наследования и полиморфизма }


uses Person;       { Объект TPerson импортируется из модуля Person }

type { объект «ВОЕННОСЛУЖАЩИЙ» }

TMilitary = object (TPerson)

mRank : string; { воинское звание }

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

procedure Report; virtual;

end;


begin

end.


Реализация методов

Отсюда приступим к реализации переопределенных методов нового объекта. Начнем с конструктора. Конечно, он мог бы повторить действия объекта-предка, но это неразумно. Ведь цель объектной технологии – упростить программирование, избежать повторов, не так ли? Избежать повтора здесь очень просто: внутри конструктора наследника вызовем конструктор предка, передав ему нужные параметры.


      TPerson.Init(aBearing, aName, aFam);


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


      inherited Init(aBearing, aName, aFam);


В таком вызове унаследованного метода трудней ошибиться. Ведь иерархия предков может быть глубокой, а представленный здесь способ вызывает метод непосредственного (ближайшего) предка, что, обычно, и требуется.

Итак, поля, унаследованные от предка, инициализированы конструктором, унаследованным от него же. Оставшееся поле mRank заполним как обычно, в результате конструктор наследника приобретет такой вид.


constructor TMilitary.Init(aBearing: integer; const aName, aFam,

      aRank : string);

begin

      inherited Init(aBearing, aName, aFam); { вызов метода предка }

      mRank:= aRank;

end;


Переходим к методу Report наследника. Здесь, вдобавок к прочим данным, надо распечатать ещё и воинское звание. Прочие данные распечатаем унаследованным методом Report, а воинское звание – дополнительным оператором печати. Вы уже догадались, что реализация метода будет такова.


procedure TMilitary.Report;

begin

      inherited Report;       { вызов метода предка }

      Writeln('Воинское звание: '+mRank);

end;


Породив «военного человека», возьмёмся за мирное строительство, создадим объект, исполняющий роль гражданского служащего. Назовем его TCivil, а род его пойдет от того же предка TPerson. У гражданских своя гордость и своя служебная лестница, ступеньки которой – категории – нумеруются числами. Хранить информацию о карьерном росте будем в числовом поле, назовем его mLevel – «уровень». Так же, как и для военного, нам придется дополнить конструктор объекта и метод распечатки Report. Ход рассуждений будет прежним, а потому не буду повторять его, сделайте эту работу сами.

Сотворив наследников «человека» – объекты TMilitary и TCivil, мы почти разобрались в механизме наследования. А где же полиморфизм? В чем он проявляется? Для ответа обратимся к динамическим объектам.

Динамические объекты

Динамические переменные знакомы нам с 52-й главы. Указатели на объекты ничем не отличаются от таковых для других типов данных. Например, указатель на тип TPerson объявляется так:


type PPerson = ^TPerson;


Теперь можно объявить переменную этого типа, взять для неё память в куче, а затем инициализировать поля конструктором.


var P : PPerson;       { указатель на объект }

begin

      New(P);       { выделение памяти в куче }

      P^.Init(1985, 'Иван', 'Грозный'); { инициализация объекта }


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

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

Сломанная кукла (СИ)
Сломанная кукла (СИ)

- Не отдавай меня им. Пожалуйста! - умоляю шепотом. Взгляд у него... Волчий! На лице шрам, щетина. Он пугает меня. Но лучше пусть будет он, чем вернуться туда, откуда я с таким трудом убежала! Она - девочка в бегах, нуждающаяся в помощи. Он - бывший спецназовец с посттравматическим. Сможет ли она довериться? Поможет ли он или вернет в руки тех, от кого она бежала? Остросюжетка Героиня в беде, девочка тонкая, но упёртая и со стержнем. Поломанная, но новая конструкция вполне функциональна. Герой - брутальный, суровый, слегка отмороженный. Оба с нелегким прошлым. А еще у нас будет маньяк, гендерная интрига для героя, марш-бросок, мужской коллектив, волкособ с дурным характером, балет, секс и жестокие сцены. Коммы временно закрыты из-за спойлеров:)

Лилиана Лаврова , Янка Рам

Современные любовные романы / Самиздат, сетевая литература / Романы