Олег Деревенец - Песни о Паскале
- Название:Песни о Паскале
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Олег Деревенец - Песни о Паскале краткое содержание
Песни о Паскале - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
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 ;
end;
PCivil = ^TCivil; { указатель на объект «ГРАЖДАНСКИЙ СЛУЖАЩИЙ» }
TCivil = object (TPerson)
mLevel : integer; { должностная категория }
constructor Init(aBearing: integer; const aName, aFam : string;
aLevel: integer);
procedure Report; virtual ;
end;
{--- Реализация объекта «ВОЕННОСЛУЖАЩИЙ» ---}
constructor TMilitary.Init(aBearing: integer; const aName, aFam,
aRank : string);
begin
inherited Init(aBearing, aName, aFam);
mRank:= aRank;
end;
procedure TMilitary.Report;
begin
inherited Report;
Writeln('Звание: '+mRank);
end;
{--- Реализация объекта «ГРАЖДАНСКИЙ СЛУЖАЩИЙ» ---}
constructor TCivil.Init(aBearing: integer; const aName, aFam : string;
aLevel: integer);
begin
inherited Init(aBearing, aName, aFam);
mLevel:= aLevel;
end;
procedure TCivil.Report;
begin
inherited Report;
Writeln('Категория: ', mLevel);
end;
var Persons : array[1..3] of PPerson; { массив указателей на ПРЕДКА }
i : integer;
begin {--- Главная программа ---}
{ Массив заполняется объектами РАЗНЫХ, но родственных типов }
Persons[1]:= New( PPerson , Init(1985, 'Иван', 'Семенов'));
Persons[2]:= New( PCivil , Init(1995, 'Мария', 'Рыбкина', 12));
Persons[3]:= New( PMilitary , Init(1985, 'Андрей', 'Быков', 'Майор'));
{ В ходе распечатки вызывается метод ФАКТИЧЕСКОГО объекта }
for i:=1 to 3 do Persons[i]^.Report;
Readln;
end.
Объяснять ли вам, из чего строят современные программы? Из сотен «умных» объектов, которые образуют ветвистую иерархию родственных связей, открывающую простор полиморфизму.
Многие объекты фирменных библиотек – это полуфабрикаты, требующие лишь небольшой настройки под конкретное применение. В ходе такой настройки программист добавляет к базовому объекту свои поля и методы. И здесь порой случается то же, что при использовании библиотечных модулей: имя, назначенное программистом, может совпасть с уже объявленным именем в предке. И тогда имена могут конфликтовать. В библиотечных модулях эта проблема решается скрытием большей части переменных, процедур и функций в невидимой извне секции реализации IMPLEMENTATION.
Схожий прием используют и в объектном программировании. Поля и методы, доступ к которым наследникам не нужен, прячут в объекте-предке так, что они становятся невидимыми за пределами предка. И тогда спрятанные имена можно использовать в наследниках повторно по иному назначению. Не будет ли здесь путаницы? Нет, поскольку методы предка не знают о новых именах и обращаются к старым. А методы наследника не видят старых имен и обращаются к новым. Разумеется, что разработчик объекта-предка тщательно отбирает те поля и методы, что потребуются создателям потомков.
Сокрытие имен объекта организовано очень просто: в объявление объекта вставляют ключевые слова PRIVATE (личный) и PUBLIC (общедоступный). Эти слова разбивают объявление объекта на две части – приватную и общедоступную, например:
type TParent = object { объект–предок }
private
A, B : integer;
function Calc(arg: integer): integer;
public
Constructor Init(a, b : integer)
function GetSum: integer; virtual;
end;
Здесь поля A и B, а также функция Calc, скрыты от взоров потомков. Поэтому программист, импортировавший объект типа TParent, может спокойно добавить в него свои поля или методы с теми же самыми именами, например, так:
type TChild = object ( TParent ) { объект–наследник }
A, B : string;
procedure Calc;
...
end;
Здесь в потомке поля A и B имеют другой тип, а имя Calc принадлежит не функции, а процедуре. Но и сейчас поля и методы предка с этими же именами все ещё существуют! Но доступны только предку, вот и все.
А если в объявлении объекта не указаны ключевые слова PRIVATE и PUBLIC? Тогда все его поля и методы по умолчанию будут общедоступными.
Итак, мы рассмотрели идеи и механизмы, лежащие в основе объектно-ориентированного программирования. К сожалению, одной главы маловато для освоения всех тонкостей этой технологии – на то есть другие книги. Объектные технологии – это настоящее и будущее программирования, не жалейте времени на их освоение. Здесь, как и во всем, важна практика. В начале главы я дал пример использования библиотеки Turbo Vision. Изучение этой и ей подобных библиотек – прекрасный способ освоения объектной технологии, подробное описание библиотеки можно найти в Сети и в литературе.
• Объектно-ориентированное программирование – это современная технология быстрой разработки крупных и надежных программ.
• Объект – это сложный тип данных, совмещающий в себе собственно данные и процедуры, обрабатывающие их.
Читать дальшеИнтервал:
Закладка: