Ответы на экзаменационные вопросы № 1-34 по дисциплине "Программирование" (Средства модульного программирования в системе Турбо-Паскаль. ООП. Объекты в динамической памяти), страница 27

Unit Persons; Interface Type Tstaff = object

Name:string[6]; Money,bonus:real; Constructor lnit(n:string; m,b:real); Function Getsum:real; virtual; Procedure Showsum; End;

Tteacher = object (Tstaff) Hours.word;

Constructor Init (n:string;m,b:real; h:word); Function Getsunrreal; virtual; End;

Implementation

Constructor Tstaff. Init; Begin

Name:= n; Money:= m; Bonus:= b End;

Function Tstaff.Getsum, Begin

Getsum:= money + bonus; End;

Procedure Tstaff. Showsum; Begin

Writeln(Getsum)

End;

Constructor Tteacher. init; Begin

Inherited Init (n,m,b); Hours:= h End;

Function Tteacher. Getsum; Begin

Getsum:= inherited Getsum + 0.01*money * Hours End;

End.

Для использования таких обектов в программе должен быть подключен Persons и описаны переменные объектных типов

Uses Persons;

Var Staff: Tstaff;

Teacher: Tteacher;

После обращений к конструкторам объектов можно вызывать другие их методы.

Staff.lnit ('Иванов',300,100);

Teacher.lnit ('Петров1,200,200,100);

Staff. ShowSum;

Teacher.ShowSum;

Если бы функция GetSum не была объявлена виртуальной, то происходило бы раннее связывание, а это значит, что при обращении к процедуре ShowSum объектов Staff и Teacher происходил бы вызов функции GetSum объекта-предка, т.е., Tstaff. Объявление функции GetSum виртуальной приводит к позднему связыванию, и поэтому при выполнении процедуры Staff.ShowSum происходит обращение к функции GetSum объекта Tstaff, а при выполнении Tteacher.ShowSum - к функции GetSum объекта Tteacher.

Проиллюстрируем использование виртуальных методов еще на одном примере. Пусть мы хотим создать модуль, который осуществлял бы передвижение по экрану различных фигур. Для простоты рассмотрим окружность и квадрат (объекты Tkrug и Tkvad). В качестве объекта-предка возьмем абстрактный тип Tnothing, в котором определим все методы, работающие с окружностью и квадратом. Метод Init, как всегда, будет инициализировать экземпляры объектов, для Tnothing этот метод может быть объявлен процедурой, поскольку объект такого типа не будет использован в программе и функции, выполняемые конструктором, не понадобятся. Для Tkrug и Tkvad метод Init должен быть определен как конструктор. Метод Show будет выводить изображение окружности и квадрата, метод Hide должен "прятать" изображение, т.е. выводить его цветом фона, метод Change будет менять координаты экземпляра объекта. Метод Fly должен перемещать изображение, т.е. в цикле последовательно вызывать методы Show, Hide и Change. Поскольку используемые Fly методы Show и Hide должны быть разными для разных объектов, то следует объявить их виртуальными:

Unitflyi; Interface

Uses graph,crt;

{абстрактный тип}

Type Tnothing = object

X,y: integer;

S vet: word;

Procedure Init (x1,y1 .integer; svet1:word); Procedure Show; virtual; Procedure Hide; virtual; Procedure change; Procedure Fly; End; Tkrug = object (Tnothing)

R:word;          {добавлено поле для радиуса}

Constructor Init (x1,y1:integer; r1,svet1:word);

{добавлен параметр - радиус} Procedure Show; virtual; Procedure Hide; virtual; End;

Tkvad = object (Tnothing) Z: integer;

Constructor Init(x1,y1,z1:integer; svetlword); Procedure Show; virtual; Procedure Hide; virtual; End; Implementation

Procedure Tnothing. Init; Begin

X:=x1;y:=y1; svet:=svet1; End;

Procedure Tnothing. Show; Begin End;

Procedure Tnothing. Hide; Begin End;

Procedure Tnothing. Change; Begin

X:=x+27: y:=y+20; End;

Procedure Tnothing. Fly; Begin                  {процедура пустая, т.к. у объектов}

While                                                           {не будет экземпляров}

(x<getmaxx) and (y<getmaxy) do

Begin

Show;

Hide;

Change

End

End;

Constructor Trug. Init: Begin

inherited Init (x1,y1,svet1); R:=r1: End;

Constructor Tkrug.Show;

Begin

Setcolor(svet);

Circle(x,y.r);

Delay(100); End;

Procedure Trug. Hide;

Begin

Setcolor(getbkcolor); Circ!e(x,y,r) End;

Constructor Tkvad.lnit;

Begin

Inherited Init(x1,y1,svet1); Z:=z1 End;

Procedure Tkvad. Show;

Begin

Setcolor(svet); Rectangle(x,y,x+z,y+z); Delay(100) End;

Procedure Tkvad.Hide;

Begin

Setcoior(getbkcolor); Rectangle(x,y,x+z,y+z)

End;