734c Паскаль. P.40. Объекты. Виртуальные методы. Позднее связывание. Сборник задач по программированию Александра Приходько
 

Сборник задач по программированию. Старая версия

 

 Приходько А. Н.

 

учебный материал, по программированию, программа, 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.

 

©   Александр Приходько    1996 - 2006

69 0