734c
Сборник задач по программированию. Старая версия
|
учебный материал, по программированию, программа, html, сервлет, процедура, файл, образование |
Паскаль. P.40. Объекты. Виртуальные методы. Позднее связывание
Объекты.
Объект это структура, состоящая из фиксированного числа компонентов. Каждый компонент
является либо полем, содержащим данные определенного типа, либо методом, выполняющим операции над полями объекта. Поля объекта описываются аналогично полям записи. В типе объекта описываются только заголовки методов, тела методов описываются в секции реализации.
Любой объект должен содержать 2 обязательных метода: конструктор и деструктор.
Объект может наследовать поля и методы из другого объекта и добавлять какие-то свои. В этом случае конструктор метода обязательно должен содержать в своем теле вызов конструктора метода, который он наследует. То же самое относится и к деструктору.
Если конструктор и деструктор не выполняют никаких действий и метод не содержит виртуальных методов, то их можно опустить и они будут заданы по умолчанию.
Виртуальные методы. Позднее связывание.
По умолчанию, методы являются статическими, однако могут, за исключением конструкторов, быть виртуальными .Компилятор разрешает ссылки на вызовы статических методов во время процесса компиляции, тогда как вызовы виртуальных методов разрешаются во время выполнения. Это иногда называют поздним связыванием.
Если объект объявляет или наследует какой-либо виртуальный метод, то поля этого объекта должны быть инициализированы посредством вызова конструктора перед вызовом любого виртуального метода. Таким образом, объект, который описывает или наследует виртуальный метод, должен также описывать или наследовать по крайней мере один метод-конструктор.
Объект может переопределять любой из методов, которые он наследует от своих предков. Если описание метода в потомке указывает тот же идентификатор метода, что и описание метода в предке, то объявление в потомке подавляет объявление в предке. Область действия переопределяющего метода расширяется до сферы действия потомка, в котором этот метод был введен, и будет оставаться таковой, пока идентификатор метода не будет переопределен снова.
Переопределение статического метода не зависит от изменения заголовка метода. В противоположность этому, переопределение виртуального метода должно сохранять порядок, типы и имена параметров, а также типы результатов функций, если таковые имеются.
Пример.
В качестве примера напишем программу на языке Паскаль, которая будет перемещать по экрану дисплея машинку по определенной траектории. Программу будем писать пошагово, на каждом шаге усложняя ее. Программа будет состоять из нескольких модулей: содержащих описания объектов-машинок, и главной части. Главная часть будет на всех этапах одинаковой и ниже приводится ее текст:
Program RunCar;
uses crt, dos, Cars4;
var
Car : MyCar4;
begin
clrscr;
Car.Init;
Car.Run;
Car.Done
end.
Шаг 1. Изображение машинки состоит из одного символа «*», который перемещается по экрану дисплея по прямой линии, слева направо с постонной скоростью.
Unit Cars;
interface
uses crt, dos;
type
MyCar = object
X, Y : integer;
constructor Init;
procedure Car; virtual;
procedure NoCar; virtual;
procedure NextPlace; virtual;
function IsStop : boolean; virtual;
procedure Move; virtual;
procedure Run;
destructor Done;
end;
implementation
constructor MyCar.Init;
begin
x:=5; y:=5;
end;
procedure MyCar.Car;
begin
gotoxy(x,y); write('*');
end;
procedure MyCar.NoCar;
begin
gotoxy(x,y); write(' ');
end;
procedure MyCar.NextPlace;
begin
x:=x+1;
end;
function MyCar.IsStop : boolean;
begin
IsStop:=(x=50);
end;
procedure MyCar.Move;
begin
delay(300); NoCar;
NextPlace; Car;
end;
procedure MyCar.Run;
begin
while not IsStop do Move
end;
destructor MyCar.Done;
begin
end;
end.
Шаг 2. Усложняем изображение машинки.
Unit Cars2;
interface
uses crt, dos, Cars;
type
MyCar2 = object(MyCar)
constructor Init;
procedure Car; virtual;
procedure NoCar; virtual;
destructor Done;
end;
implementation
constructor MyCar2.Init;
begin
MyCar.Init
end;
procedure MyCar2.Car;
begin
gotoxy(x,y-2); write(' * ');
gotoxy(x,y-1); write(' *** ');
gotoxy(x,y); write('o***o');
end;
procedure MyCar2.NoCar;
begin
gotoxy(x,y-2); write(' ');
gotoxy(x,y-1); write(' ');
gotoxy(x,y); write(' ');
end;
destructor MyCar2.Done;
begin
MyCar.Done
end;
end.
Шаг 3. Изменяем траекторию движения машинки. Теперь она будет двигать по спирали..
Unit Cars3;
interface
uses crt, dos, Cars2;
type
MyCar3 = object(MyCar2)
Direction : (Left, Right, Up, Down);
Shift : integer;
constructor Init;
procedure NextPlace; virtual;
function IsStop : boolean; virtual;
destructor Done;
end;
implementation
constructor MyCar3.Init;
begin
MyCar2.Init;
Direction:=Right;
Shift:=0;
end;
procedure MyCar3.NextPlace;
begin
case Direction of
Left: begin
x:=x-1;
if x=5+Shift then Direction:=Up;
end;
Right: begin
x:=x+1;
if x=55-Shift then Direction:=Down;
end;
Up: begin
y:=y-1;
if y=5+Shift then Direction:=Right;
end;
Down: begin
y:=y+1;
if y=20-Shift then begin
Direction:=Left;
Shift:=Shift+1;
end;
end;
end;
end;
function MyCar3.IsStop : boolean;
begin
IsStop:=(y=12) and (x>20) and (Direction=Right);
end;
destructor MyCar3.Done;
begin
MyCar2.Done
end;
end.
Шаг 4. Изменяем скорость движения машинки. Теперь она будет двигаться с постоянно увеличивающейся скоростью.
Unit Cars4;
interface
uses crt, dos, Cars3;
type
MyCar4 = object(MyCar3)
DDelay : integer;
constructor Init;
procedure Move; virtual;
destructor Done;
end;
implementation
constructor MyCar4.Init;
begin
MyCar3.Init;
DDelay:=1500;
end;
procedure MyCar4.Move;
begin
Ddelay:= Ddelay-2;
delay(DDelay); NoCar;
NextPlace; Car;
end;
destructor MyCar4.Done;
begin
MyCar3.Done
end;
end.
Этот пример протестирован в системе программирования Turbo Pascal 6.0.
|