Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл: Источник:
Скачиваний:
98
Добавлен:
04.03.2014
Размер:
593.92 Кб
Скачать

Init(x1,y1);

show;

end; {point.shift}

procedure square.init(X1,Y1,side1:integer);

begin

side:=side1;

point.init(X1,Y1);

end; {square.init}

procedure square.show;

begin

visible:=true;

rectangle(X-side div 2, X- side div 2, X+side div 2, Y+ side div 2);

end; {sguare.show}

procedure square.hide;

var temp:word;

begin

temp :=getcolor;

setcolor(getbkcolor);

show;

visible:=false;

Setcolor(temp);

end; {sguare.hide}

procedure square.shift(X1,Y1:integer);

begin

hide;

X:=X1;

Y:=Y1;

show;

end; {sguare.shift}

procedure square.explode(step:integer);

begin

hide;

inc(side,step);

show;

end;

end.

Чтобы использовать эти типы объектов и методы, в своей программе достаточно определить экземпляры типа Point и Square:

program ex1_OOP;

uses crt,graph,obj1_OOP;

var gm,gd :integer;

XP :point;

XS :square;

I :word;

Begin

gd:=detect;

InitGraph(gd,gm,'C:\BP\BGI');

if GraphResult<>GrOk then Halt(1);

with XP do

begin

init(100,100);

show;

readln;

shift(200,200);

readln;

hide;

end;

with XS do begin

init(100,100,50);

show;

readln;

shift(200,200);

readln;

for i:= 1 to 20 do

begin

explode(10);

delay(200);

end;

readln;

hide;

end;

closeGraph;

End.

В этом примере инициализируется точка, затем она показывается на экране, перемещается в новое место и прячется. Затем инициализируется квадрат, показывается на экране, в 20 раз увеличивает свои линейные размеры на 5 точек и стирается.

Когда родительский тип определен, наследуемые правила могут быть заменены (а могут и использоваться). Для замены унаследованного правила просто определите новое правило с тем же именем, как и унаследованное, но с другим телом и (при необходимости) с другим набором параметров. Логика компилятора в решении вызовов методов такова: компилятор сначала ищет метод с таким именем, определенный в пределах типа объекта. Тип Square определяет методы с именами Init, Show, Hide, Shift и Explode. Если тип Square должен вызвать один из этих методов, компилятор заменит этот вызов адресом одного из собственных методов объекта Square.

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

Пользователь может создавать новых потомков и не имея исходного кода Unit (это важно в коммерческих приложениях). Следующий пример иллюстрирует эту возможность, порождая новый объект PaintSquare (закрашенный квадрат), базируясь только на тексте секции Interface для модуля Obj1_OOP.

Unit obj2_OOP;

Interface

Uses Graph, obj1_OOP;

Type PaintSquare = Object(Square)

SquareColor: Word;

Procedure Init(X1,Y1,Side1,Color:Integer);

Procedure Show;

Procedure Hide;

Procedure Shift(X1,Y1:Integer);

Procedure Explode(Step:Integer);

End;

Implementation

Procedure PaintSquare.Init(X1,Y1,Side1,Color:Integer);

Begin

Square.Init(X1,Y1,Side1);

SquareColor :=Color;

End;

Procedure PaintSquare.Show;

Var Temp : Word;

Begin

Square.Show;

Temp:=GetColor;

SetFillStyle(SolidFill, SquareColor);

FloodFill(X,Y,Temp);

SetColor(Temp);

End;

Procedure PaintSquare.Hide;

Begin

SetFillStyle(SolidFill,GetBkColor);

FloodFill(X,Y,GetBkColor);

Square.Hide;

End;

Procedure PaintSquare.Shift(X1,Y1 : Integer);

Begin

Hide;

Init(X1,Y1,Side,SquareColor);

Show;

End;

Procedure PaintSquare.Explode(Step : Integer);

Begin

Hide;

Inc(Side,Step);

Init(X,Y,Side,SquareColor);

Show;

End;

End.

Используется модуль аналогично предыдущему. В следующем примере инициализируется закрашенный квадрат, затем он показывается на экране, перемещается на новое место и, наконец в 20 раз увеличивает линейные размеры на 5 точек, а затем возвращается в исходное состояние путем последовательного уменьшения.

Program EX2_OOP;

Uses Crt, Graph, obj2_OOP;

var gd,gm : integer;

XPS : PaintSquare;

I : Word;

begin

gd:=Detect;

InitGraph(gd,gm,'C:\BP\BGI');

If graphResult<>GrOk then Halt(1);

With XPS do

Begin

Init(100,100,50,14);

Show;

Readln;

Shift(200,200);

Readln;

For i:=1 to 20 do Begin

Explode(5);

Delay(200);

End;

Readln;

For i:=1 to 20 do Begin

Explode(-5);

Delay(200);

End;

Readln;

CloseGraph;

End;

End.

1.5. Виртуальные методы и полиморфизм

Все методы, которые мы рассматривали до этого, были статическими, т.е. компилятор размещает их и разрешает все ссылки во время компиляции. В Турбо Паскале существует возможность связывания данных с методами на этапе выполнения программы, такое связывание называется поздним. При позднем связывании используются так называемые виртуальные методы. Виртуальные методы реализуют чрезвычайно мощное средство для обобщения, которое называется полиморфизмом.

Полиморфизм - свойство, позволяющее называть разные алгоритмические действия одним именем. Такое действие совместно используется в иерархии объектов, причем каждый объект в этой иерархии реализует это действие своими собственными, пригодными для него способами.

Метод делается виртуальным, когда за его определением в типе объекта ставится служебное (зарезервированное) слово Virtual. Надо запомнить, что, если вы определяете метод в родительском типе как Virtual, все методы с тем же именем в любом из потомков также должны быть описаны как Virtual.

Вот как может произойти виртуализация рассмотренных выше графических объектов:

Unit obj3_OOP;