Дополню немного.
Есть 2 типа функций. Просто функции и методы класса.
Для первого варианта можно так:
Код:
type
TFunc = function (x : double) : double;
function f1(x : double) : double;
begin
result := x+1; // просто для примера
end;
function f2(x : double) : double;
begin
result := x-1;
end;
function CalcFunc(x1, x2, dx : double; func : TFunc) : double;
var
i : double;
begin
// просто бред для примера
result := 0;
i := x1;
while i <= x2 do
begin
result := result + func(i);
i := i + dx;
end;
end;
// где-то вызов
begin
writeln('f1 ->', CalcFunc(1,5,0.2,f1);
writeln('f2 ->', CalcFunc(1,5,0.2,f2);
end;
Для второго случая есть 2 подварианта.
а. Тоже самое, только тип описан как
Код:
type
TFunc = function (x : double) : double of object;
тогда в основную функцию можно передавать методы любого класса.
б. Передавать объект класса. тогда их можно "нанаследовать" от одного родителя. Там есть еще вариант с мета классом.
Код:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TFuncClass = class
class function Name : String; virtual;
class function f(x : double) : double; virtual;
end;
TMetaClass = class of TFuncClass;
TF1 = class(TFuncClass)
class function Name : String; override;
class function f(x : double) : double; override;
end;
TF2 = class(TFuncClass)
class function Name : String; override;
class function f(x : double) : double; override;
end;
TForm2 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
function Calc(x1, x2, dx : double; cls : TMetaClass) : double;
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
class function TFuncClass.Name : String;
begin
result := 'TFuncClass';
end;
class function TFuncClass.f(x : double) : double;
begin
Raise Exception.Create('Should not be called.');
end;
class function TF1.Name : String;
begin
result := 'f1';
end;
class function TF1.f(x : double) : double;
begin
result := x + 1;
end;
class function TF2.Name : String;
begin
result := 'f2';
end;
class function TF2.f(x : double) : double;
begin
result := x - 1;
end;
function TForm2.Calc(x1, x2, dx : double; cls : TMetaClass) : double;
var
i : double;
begin
result := 0;
i := x1;
while i <= x2 do
begin
result := result + cls.f(i);
i := i + dx;
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
Memo1.Lines.Add(Format('class %s, name %s -> %.4f',[TF1.ClassName,TF1.Name,Calc(1,5,0.2,TF1)]));
Memo1.Lines.Add(Format('class %s, name %s -> %.4f',[TF2.ClassName,TF2.Name,Calc(1,5,0.2,TF2)]));
end;
end.
В результате нажатия на кнопку в Memo имеем:
Код:
class TF1, name f1 -> 78,0000
class TF2, name f2 -> 38,0000
Обрати внимание на тип TMetaClass.
ЗЫ. Я там совместил вызов собственно функции, форматирование строки и ее добавление в Memo. Думаю, разберешся.
ЗЗЫ. Для особо умных. Мне просто было интересно - помню ли я как работать с метаклассами, последний раз делал такое лет 8 назад. Что-то еще помню, написал с первого раза без ошибок.