Чтение онлайн

на главную - закладки

Жанры

Шрифт:

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

type Электроприбор = object

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

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

end;

Здесь встречаем новое «волшебное» словечко – VIRTUAL, что значит «воображаемый». Это ключевое слово Паскаля следует за объявлением тех методов объекта, которые разрешено изменять в его наследниках. Изменение

метода в наследниках называют переопределением метода. Итак, слово 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; { фамилия }

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

procedure Report; virtual;

end;

TMilitary = object (TPerson)

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

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

aRank : string);

procedure Report; virtual;

end;

Подытожим все изменения. В предке TPerson процедура Report стала виртуальной. В наследнике TMilitary добавлено поле mRank, а также изменены два метода: конструктор и процедура Report.

«Отселение» в отдельный модуль

Настало время реализовать методы наследника. Но прежде, чем взяться за это, совершим одно полезное дельце – переместим объект-предок TPerson в отдельный модуль. Именно так поступают профессионалы, создавая библиотеки объектов. Порядок создания программного модуля подробно изложен в главе 59, вкратце я напомню основные шаги.

Итак, создайте новый файл, перенесите туда через буфер обмена объявление типа TPerson и реализацию его методов. Объявление объекта разместите в секции INTERFACE модуля, а реализацию – в секции IMPLEMENTATION. И не забудьте объявить виртуальной процедуру Report. Дайте модулю имя PERSON и сохраните под именем «PERSON.PAS». У вас получится файл, показанный ниже. В нём объявлен ещё один тип данных – указатель на объект PPerson, но к нему обратимся позже.

unit Person; { Модуль, содержащий описание и реализацию объекта «ЧЕЛОВЕК» }

interface

type PPerson = ^TPerson; { указатель на объект «ЧЕЛОВЕК» }

TPerson = object

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

mName : string; { имя }

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

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

procedure Report; virtual;

end;

implementation

{--- Реализация объекта «ЧЕЛОВЕК» ---}

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

begin

mBearing := aBearing;

mName := aName;

mFam := aFam;

end;

procedure TPerson.Report;

begin

Writeln(mBearing:6, 'Фамилия: '+mFam:20, ' Имя: '+mName);

end;

end.

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

USES Person;

Поделиться:
Популярные книги

Мастер 3

Чащин Валерий
3. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 3

Сумеречный Стрелок 3

Карелин Сергей Витальевич
3. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 3

Облачный полк

Эдуард Веркин
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Облачный полк

Столкновение

Хабра Бал
1. Вне льда
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Столкновение

Кротовский, не начинайте

Парсиев Дмитрий
2. РОС: Изнанка Империи
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Кротовский, не начинайте

Измена. Право на любовь

Арская Арина
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на любовь

Законы Рода. Том 4

Flow Ascold
4. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 4

Невеста напрокат

Завгородняя Анна Александровна
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Невеста напрокат

Хозяйка усадьбы, или Графиня поневоле

Рамис Кира
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Хозяйка усадьбы, или Графиня поневоле

Город Богов

Парсиев Дмитрий
1. Профсоюз водителей грузовых драконов
Фантастика:
юмористическая фантастика
детективная фантастика
попаданцы
5.00
рейтинг книги
Город Богов

Двойня для босса. Стерильные чувства

Лесневская Вероника
Любовные романы:
современные любовные романы
6.90
рейтинг книги
Двойня для босса. Стерильные чувства

Вперед в прошлое 3

Ратманов Денис
3. Вперёд в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 3

Возвышение Меркурия. Книга 2

Кронос Александр
2. Меркурий
Фантастика:
фэнтези
5.00
рейтинг книги
Возвышение Меркурия. Книга 2

Барон не играет по правилам

Ренгач Евгений
1. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон не играет по правилам