delphi通过函数名动态调用函数的方法(方便功能的扩展)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TMyCacl = class(TObject)
  public
    { Public declarations }
    function DynamicFun(funName: string; const a, b: integer): integer;
  published
    function add(const a, b: integer): integer;
    function dec(const a, b: integer): integer;
  end;
  TNewMyCacl = class(TMyCacl)
  published
    function Multi(const a, b: integer): integer;
  end;
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyCacl }

function TMyCacl.add(const a, b: integer): integer;
begin
  result := a + b;
end;

function TMyCacl.dec(const a, b: integer): integer;
begin
  result := a - b;
end;

function TMyCacl.DynamicFun(funName: string;const  a, b: integer): integer;
var
  pfun: function(const a, b: integer): integer of object;
begin
  if self.MethodAddress(funName) <> nil then
  begin
    TMethod(pfun).Code := MethodAddress(funName);
    result := pfun(a, b);
  end
  else  result := 0;
end;

{ TNewMyCacl }

function TNewMyCacl.Multi(const a, b: integer): integer;
begin
  result := a * b;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  tmp: TMyCacl;
  i: integer;
begin
  tmp := TNewMyCacl.Create();
  if tmp.MethodAddress('Multi') <> nil  then
  begin
    i := tmp.DynamicFun('Multi', 102, 3);
    showmessage(inttostr(i));
  end;
  tmp.Free;
end;

end.

以上代码实现了类中通过函数名动态调用函数的方法,这样处理的一个优点是使类的复用性与扩展性得到加强,比如上例中,之前有一个类TMyCacl,能实现对a与b做加法与减法运算,

假如今后需求变化,需要增加其他运算时,可通过继承该类,重新写一个新运算方法,但是调用还用利用DynamicFun函数,这样在原来的类不要做修改的前提下,很好的实现功能的扩展。

这里一定要注意的是,需要被动态条用的函数一定要是 published 类型,否则MethodAddress将无法获取该函数。

原文地址:https://www.cnblogs.com/tangqs/p/3221344.html