Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование лекции.doc
Скачиваний:
49
Добавлен:
12.11.2019
Размер:
5.53 Mб
Скачать

10.4. Параметры-процедуры

Объект используется внешней программой, которая обеспечивает весь интерфейс пользователя: кнопки, индикаторы и пр. И здесь возникает изрядная проблема: методы объекта при своем выполнении должны взаимодействовать с элементами интерфейса. Скажем, при смене частоты вращения на экране должен «ползать» полосковый индикатор. Но ведь объект пишется один раз и должен быть пригоден для использования в разных программах, с разным интерфейсом. Поэтому, как правило, внутри объекта никаких ссылок на формы, кнопки, поля ввода… нет .

Как же быть? Выход, разумеется, есть. Можно передать в объект ссылку на любую процедуру, описанную во внешней программе, и внутри методов объекта эту процедуру вызывать. Передача ссылки на процедуру (точнее, на метод другого объекта – такая процедура может быть, например, методом главной формы программы) требует использования особого типа данных, который описывается как

TYPE TP=procedure of object;

В переменной типа TP может храниться адрес метода любого другого объекта. В объекте TMotor создадим поле p типа TP. При создании объекта нужно гарантировать, что в поле p будет занесен адрес процедуры из внешней программы. Для этого достаточно ввести параметр у метода-конструктора Create:

CONSTRUCTOR TMotor.Create(pp:TP);

BEGIN

INHERITED Create;

p:=pp; { запоминаем ссылку на процедуру в поле p }

RPM:=0; { начальная частота }

Power:=0; { начальная потребляемая мощность }

br:=false; { аварии пока нет }

Direction:=CLOCKWISE { по часовой }

END;

Хочешь создать наш объект – изволь подать ему на вход процедуру.

Теперь внутри методов в любом месте можно вызвать внешнюю процедуру, просто написав p (как это было сделано в методе Feed).

Теперь соберем все сказанное вместе, да еще добавим метод Start, разгоняющий мотор до номинальной частоты, Stop (плавное торможение) и Abort (авария):

unit motor;

INTERFACE

TYPE Tdir=(CLOCKWISE, COUNTERCLOCKWISE);

TP=procedure of object; { см. следующий раздел методички!}

TMotor=CLASS

private

{ поля }

RPM:WORD; { частота вращения }

Power:REAL; { мощность }

Direction:TDir; { направление вращения }

p:TP;

br:boolean; { авария }

PROCEDURE Feed(newRPM:WORD); { смена частоты }

FUNCTION GetRPM:word;

FUNCTION GetPower:REAL;

FUNCTION GetNominal: WORD;

FUNCTION GetDr: TDir;

PROCEDURE Flip(newd:TDir);

public

{ СВОЙСТВА }

property n:word READ GetRPM WRITE Feed;

property pwr:real read GetPower;

property Nominal:WORD read GetNominal;

property dir:TDir read GetDr write Flip;

{ МЕТОДЫ }

CONSTRUCTOR Create(PP:TP);

DESTRUCTOR Free;

PROCEDURE Start; { запуск }

PROCEDURE Stop; { останов }

PROCEDURE Abort; { аварийный стоп }

END;

implementation

uses windows;

function TMotor.GetNominal:word;

begin

result:=1000; { номинальная частота вращения }

end;

function TMotor.GetDr:TDir;

begin

result:=direction

end;

CONSTRUCTOR TMotor.Create(pp:TP);

BEGIN

INHERITED Create;

p:=pp;

RPM:=0;

Power:=0;

br:=false;

Direction:=CLOCKWISE

END;

DESTRUCTOR TMotor.Free;

BEGIN

END;

function TMotor.GetRPM:word;

begin

result:=rpm

end;

FUNCTION TMotor.GetPower:REAL;

BEGIN

GetPower:=формула для вычисления потребляемой мощности

END;

PROCEDURE TMotor.Start;

BEGIN

br:=false; { для пуска после аварии }

Feed(Nominal)

END;

PROCEDURE TMotor.Stop;

BEGIN

Feed(0)

END;

PROCEDURE TMotor.Feed(newRPM:WORD);

VAR i:WORD;

s:INTEGER;

BEGIN

IF RPM-newRPM>0 THEN

s:=-1

ELSE

s:=1;

FOR i:=1 TO ABS(RPM-newRPM) DO

BEGIN

if br then exit;

RPM:=RPM+s;

Sleep(10);

p;

Power:=GetPower

END

END;

PROCEDURE TMotor.Flip(newd:TDir);

VAR oldRPM:WORD;

BEGIN

IF (RPM=0) or (direction=newd) THEN { мотор стоит? ничего не делаем }

EXIT;

oldRPM:=RPM; { запомнили текущую частоту }

Feed(0); { остановились }

Direction:=newd;

Feed(oldRPM) { установили прежнее значение частоты }

END;

PROCEDURE TMotor.Abort; { аварийный останов }

BEGIN

br:=true;

RPM:=0;

Power:=0;

p

END;

end.