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

В серьезных программах объекты обычно используют динамически, а выделение памяти и инициализацию выполняют там на каждом шагу. Потому в Паскаль введена функция New, совмещающая эти действия. Функция New подобна процедуре New, но вдобавок вызывает ещё и конструктор объекта. Функция принимает два странных параметра: тип-указатель на объект и конструктор этого объекта, а возвращает указатель на созданный объект. Так, динамический объект типа TPerson может быть порожден и инициализирован одним оператором.


      P:= New(PPerson, Init(1985, 'Иван', 'Грозный'));


Обратите внимание, что первый параметр функции – это тип-указатель PPerson, а не тип объекта TPerson!

Примечание. В языке Delphi и совместимом с ним режиме Free Pascal применяют иной синтаксис вызова конструктора, например:


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

...

P:= TPerson.Init(1985, 'Иван', 'Грозный'); { создается динамический объект }


Дело в том, что все объекты в Delphi – это динамические переменные, и переменная типа TPerson является указателем на объект. Для создания таких объектов применяют не функцию New, а вызов конструктора с префиксом, совпадающим с названием типа объекта.

Полиморфизм

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


var P1 : PPerson; { указатель на предка }

      P2 : PMilitary; { указатель на потомка }

      P3 : PCivil;       { указатель на потомка }


Здесь P1 является указателем на предка, а P2 и P3 – на разных его потомков. Отчасти полиморфизм состоит в том, что указателю на предка разрешено присваивать указатели на любого его потомка, то есть следующие операторы не вызовут протеста компилятора.


      P1:= P2;

      P1:= P3;


Скажете, пустая формальность? Зря вы так! Воистину здесь скрыт глубокий смысл, поскольку через указатель на предка можно вызывать методы его потомков. Но при условии, что эти методы унаследованы от предка как виртуальные. Так, в следующем примере указателю P1 трижды присваиваются указатели на объекты разных типов: сначала на предка TPerson, а затем на двух его потомков, после чего всякий раз вызывается виртуальный метод Report. Но в реальности происходит вызов трех разных методов Report – соответственно типу объекта, на который в текущий момент ссылается указатель P1. Так срабатывает механика полиморфизма!


      P1:= New(PPerson, Init(1985, 'Иван', 'Грозный'));

      P1^.Report;       { вызывается TPerson.Report }

      P1:= New(PCivil, Init(1995, 'Мария', 'Рыбкина', 12));

      P1^.Report;       { вызывается TCivil.Report }

      P1:= New(PMilitary, Init(1985, 'Андрей', 'Быков', 'Майор'));

      P1^.Report;       { вызывается TMilitary.Report }


Кажется, что полиморфизм одушевляет объект и делает его умнее: объект сам «понимает», как ему исполнить то, или иное желание программиста. Тот лишь вызывает нужный метод, не вникая в детали. Это похоже на управление телевизором или другим прибором. Стоит подать напряжение, и все они включатся: хоть и по-разному, но каждый по-своему правильно.

Но мощная механика полиморфизма срабатывает лишь для родственных объектов, состоящих в отношении предок-потомок. Именно в таких отношениях находятся созданные нами объекты. А вот пример иного рода.


type TA = object

      constructor Init;

      procedure Report; virtual;

      end;


      TB = object

      constructor Init;

      procedure Report; virtual;

      end;


Здесь объявлены два типа объектов с одноименными виртуальными методами. Но полиморфизмом тут и не пахнет, поскольку объекты не родственны меж собой!

В завершение темы изучите программу «P_61_3», где собрано все, что было сказано о «человечьих» объектах.


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


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


type PMilitary = ^TMilitary; { указатель на объект «ВОЕННОСЛУЖАЩИЙ» }

      TMilitary = object (TPerson)

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

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

      aRank : string);

      procedure Report; virtual;

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

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

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

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

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

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