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