FPC knows static class methods in classes: these are class methods that have the Static keyword
at the end. These methods behave completely like regular procedures or functions. This means
that:
- They do not have a Self parameter. As a result, they cannot access properties or fields
or regular methods.
- They cannot be virtual.
- They can be assigned to regular procedural variables.
Their use is mainly to include the method in the namespace of the class as opposed to having the
procedure in the namespace of the unit. Note that they do have access to all class variables, types
etc, meaning something like this is possible:
{$mode objfpc}
{$h+}
Type
TA = Class(TObject)
Private
class var myprivatea : integer;
public
class Function GetA : Integer; static;
class Procedure SetA(AValue : Integer); static;
end;
Class Function TA.GetA : Integer;
begin
Result:=myprivateA;
end;
Class Procedure TA.SetA(AValue : integer);
begin
myprivateA:=AValue;
end;
begin
TA.SetA(123);
Writeln(TA.MyPrivateA);
end.
Which will output 123, when run.
In the implementation of a static class method, the Self identifier is not available. The method
behaves as if Self is hardcoded to the declared class, not the actual class with which it was called.
In regular class methods, Self contains the Actual class for which the method was called. The
following example makes this clear:
Type
TA = Class
Class procedure DoIt; virtual;
Class Procedure DoitStatic; static;
end;
TB = CLass(TA)
Class procedure DoIt; override;
end;
Class procedure TA.DOit;
begin
Writeln('TA.Doit : ',Self.ClassName);
end;
Class procedure TA.DOitStatic;
begin
Doit;
Writeln('TA.DoitStatic : ',ClassName);
end;
Class procedure TB.DoIt;
begin
Inherited;
Writeln('TB.Doit : ',Self.ClassName);
end;
begin
Writeln('Through static method:');
TB.DoItStatic;
Writeln('Through class method:');
TB.Doit;
end.
When run, this example will print:
Through static method:
TA.Doit : TA
TA.DoitStatic : TA
Through class method:
TA.Doit : TB
TB.Doit : TB
For the static class method, even though it was called using TB, the class (Self, if it were available)
is set to TA, the class in which the static method was defined. For the class method, the class is set
to the actual class used to call the method (TB).