Иллюстрированный самоучитель по Tirbo Pascal


Полиформные коллекции - часть 3


H := Random(GetMaxY div 2) {Высота} 

end;

Procedure TRectangle.Draw; 

{Вычерчивает прямоугольник} 

begin

Rectangle(X, Y, X+W, Y+H) 

end;

После того как определены нужные объекты, не составляет особого труда поместить эти объекты в коллекцию и вывести их на экран. Например, для вывода всех элементов коллекции можно использовать такую процедуру:

Procedure DrawAll (C: PCollection) ; 

{Выводит все элементы полиморфной коллекции} 

Procedure DrawItem(p: PGraphObject); far; 

begin

p.Draw {Это и есть полиморфизм в действии!} 

end; 

begin

С.ForEach(@DrawItem) 

end;

Как видим, в процедуре DrawItem полиморфизм используется дважды: во-первых, метод ForEach обращается к ней, передавая в качестве параметра обращения нетипизированный указатель на элемент коллекции; это позволяет трактовать параметр как указатель на любой объект, в том числе и на TGraphObject. Во-вторых, в процедуре используется обращение к виртуальному методу объекта-родителя Draw: поскольку этот метод перекрывается во всех потомках, каждый из них будет использовать свой метод Draw для вывода на экран.

Сформируем программу, поместив в нее вместо, точек уже рассмотренные фрагменты:

Uses Objects,Graph,CRT; 

type

.....

Constructor TGraphObject.Init;

.....

Procedure TGraphObject.Draw;

.....

Constructor TPoint.Init;

.....

Procedure TPoint.Draw;

.....

Constructor TCircle.Init;

.....

Procedure TCircle.Draw;

.....

Constructor TRectangle.Init;

.....

Procedure TRectangle.Draw;

.....

Procedure DrawAll(C: PCollection);

.....

var

a, r, k: Integer; 

List: PCollection; 

p: Pointer;

begin . a := 0;

{Инициируем графический режим работы экрана:} 

InitGraph(a, r, '\TP\BGI'); 

r := GraphResult; if r <> 0 then

WriteLn(GraphErrorMsg(r)) {Ошибка инициации} 

else 

begin

{Создаем коллекцию:}

List := New(PCollection, Init (20,5)); 

{Наполняем ее 20 элементами:} 

for k := 1 to 20 do 

begin

case k mod 3 of 

0: p := New(PPoint, Init); 

1: p := New(PCircle, Init);

2: p := New(PRectangle, Init)

end;

if p <> NIL then List.Insert(p) 

end ;

DrawAll(List) ; {Выводим на экран все элементы} 

While not KeyPressed do;{Ждем нажатия на любую клавишу} 

CloseGraph {Возвращаемся в текстовый режим} 

end 

end.

В этой программе предполагается, что драйвер графического экрана расположен в каталоге \TF\BGI на текущем диске. Если это не так, следует указать маршрут поиска

этого драйвера в качестве параметра обращения к процедуре InitGraph. Кроме того, каталог, содержащий стандартную графическую библиотеку Graph, должен быть указан опцией Options/Directories/Unit directories, если, разумеется, библиотека не содержится в текущем каталоге.

 




- Начало -  - Назад -  - Вперед -



Книжный магазин