|
Я завершила экзамен 90 баллов на 5. Сертификат не заказала. Сейчас пытаюсь найти как его заказать. у меня указано экзамен пройден баллы оценка видно, а чтоб заказать сертификат нигде не видно. |
Иерархии объектов. Работа с объектами в динамической памяти
Наследование
Презентацию к данной работе Вы можете скачать
здесь.
Управлять большим количеством разрозненных объектов достаточно сложно. С этой проблемой можно справиться путем упорядочивания и ранжирования объектов, то есть объединяя общие для нескольких объектов свойства в одном объекте и используя этот объект в качестве базового.
Эту возможность предоставляет механизм наследования. Он позволяет строить иерархии, в которых объекты-потомки получают свойства объектов-предков и могут дополнять их или изменять. Таким образом, наследование обеспечивает возможность повторного использования кода.
Объекты, расположенные ближе к началу иерархии, объединяют в себе наиболее общие черты для всех нижележащих объектов. По мере продвижения вниз по иерархии объекты приобретают все больше конкретных особенностей.
Объект в Паскале может иметь произвольное количество потомков и только одного предка. При описании объекта имя его предка записывается в круглых скобках после ключевого слова object.
Допустим, нам требуется ввести в игру еще один тип персонажей, который должен обладать свойствами объекта monster, но по-другому выглядеть и атаковать. Будет логично сделать новый объект потомком объекта monster. Проанализировав код методов этого объекта, переопределим только те, которые реализуются по-другому ( пример 7.1).
type daemon = object (monster)
procedure init(x_, y_, health_, ammo_, magic_ : word);
procedure attack;
procedure draw;
procedure erase;
procedure wizardry;
private
magic : word;
end;
{ ------------------------- реализация методов объекта daemon ----------------- }
procedure daemon.init(x_, y_, health_, ammo_, magic_ : word);
begin
inherited init(x_, y_, health_, ammo_);
color := green;
magic := magic_;
end;
procedure daemon.attack; { --------------------------------- daemon.attack ---- }
begin
if ammo = 0 then exit;
dec(ammo);
if magic > 0 then begin
outtextXY(x + 15, y, 'БУ-БУХ!'); dec(magic); end
else
outtextXY(x + 15, y, 'бу-бух!');
end;
procedure daemon.draw; { ----------------------------------- daemon.draw ---- }
begin
setcolor(color); outtextXY(x, y, '%)');
end;
procedure daemon.erase; { ----------------------------------- daemon.erase ---- }
begin
setcolor(black); outtextXY(x, y, '%)');
end;
procedure daemon.wizardry; { -------------------------------- daemon.wizardry - }
begin
if magic = 0 then exit;
outtextXY(x + 15, y, 'крибле-крабле-бумс!'); dec(magic);
end;
Листинг
7.1.
Переопределение методов после добавления нового типа персонажей
Наследование полей.Унаследованные поля доступны в объекте точно так же, как и его собственные. Изменить или удалить поле при наследовании нельзя.Объект daemon содержит все поля своего предка и одно собственное поле magic, в котором хранится "магическая сила" объекта.
Наследование методов.В потомке объекта можно не только описывать новые методы, но и переопределять существующие. Метод можно переопределить либо полностью, либо дополнив метод предка.
В объекте daemon описан новый метод wizardry, с помощью которого объект применяет свою магическую силу, а метод инициализации init переопределен, потому что количество полей объекта изменилось. Однако необходимость задавать значения унаследованным полям осталась, и соответствующий метод есть в объекте monster, поэтому из нового метода инициализации сначала вызывается старый, а затем выполняются дополнительные действия (присваивание значения полю ammo ).
Вызов метода предка из метода потомка выполняется с помощью ключевого слова inherited (унаследованный). Можно вызвать метод предка и явным образом с помощью конструкции monster.init.
Методы отрисовки draw и erase также переопределены, потому что изображение демона отличается от изображения монстра и, следовательно, формируется другой последовательностью подпрограмм (для простоты представим демона в виде "смайлика").
Переопределен и метод attack: теперь атака выполняется по-разному в зависимости от наличия магической силы.
Чтобы перемещать демона, требуется выполнить те же действия, что записаны в методе move для перемещения монстра: необходимо стереть его изображение на старом месте, обновить координаты и нарисовать на новом месте. На первый взгляд, можно без проблем унаследовать этот метод, а также метод hit. Так мы и поступим.
Добавим описание объекта daemon в интерфейсную часть модуля monsters, а тексты его методов — в раздел реализации. Проверим работу новых методов с помощью программы:
program test_inheritance;
uses graph, crt, monsters;
var Vasia : daemon;
gd, gm : integer;
begin
gd := detect; initgraph(gd, gm, '...');
if graphresult <> grOk then begin
writeln('ошибка инициализации графики'); exit end;
Vasia.init(100, 100, 20, 10, 6);
Vasia.draw; Vasia.attack;
readln;
Vasia.erase;
readln;
end.И в предке, и в потомке есть одноименные методы. Вызывается всегда тот метод, который соответствует типу объекта, потому что при вызове указывается имя экземпляра заданного типа ( рис. 7.1). Это можно рассматривать как простейший вид полиморфизма.
