Consider the following Delphi code:
unit Unit2;
interface
uses Dialogs;
type
TNamedObj = class
private
FObjName: string;
public
constructor Create(const AName: string);
procedure ShowName1;
class procedure ShowName2(Obj: TNamedObj); static;
end;
implementation
constructor TNamedObj.Create(const AName: string);
begin
FObjName:= AName;
end;
procedure TNamedObj.ShowName1;
begin
ShowMessage(FObjName);
end;
class procedure TNamedObj.ShowName2(Obj: TNamedObj);
begin
ShowMessage(Obj.FObjName);
end;
end.
At a first glance ShowName2 looks like a useless addition. It does the same thing as ShowName1, and the compiler generates identical code for both.
Static class methods were made type compatible with ordinary procedures (functions). In the above example the static class method implementation of ShowName is type compatible with
type TShowProc = procedure(Obj: TNamedObj);
and that allows you to pass ShowName2 code as an argument:
type
TShowProc = procedure(Obj: TNamedObj);
procedure TestShowName2(Proc: TShowProc);
var
Obj: TNamedObj;
begin
Obj:= TNamedObj.Create('Apple');
Proc(Obj);
Obj.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TestShowName2(TNamedObj.ShowName2);
end;
You need some unclean hackish trick to do the same with an object method:
type
TShowMeth = procedure of object;
procedure TestShowName1(Proc: Pointer);
var
Obj: TNamedObj;
Meth: TMethod;
begin
Obj:= TNamedObj.Create('Apple');
Meth.Data:= Obj;
Meth.Code:= Proc;
TShowMeth(Meth);
Obj.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
TestShowName1(@TNamedObj.ShowName1);
end;
See also the related SO question.