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).