Delphi comes with support for both OOP and procedural code, something you come across less every day as more languages move over to an OOP-only structure. Because of this static code in Delphi is often added as procedural code, which makes sense of course. However, Delphi also has the ability to add static members to classes which can be quite useful at times.
Delphi features several different kinds of static members. The first are fields and properties. A Delphi class can contain any number of static fields and properties which work the exact same way as a regular member would, however they can only be accessed in a static context. Same as with regular properties a static property can retrieve values by calling methods, however all of these accessors and mutators have to be static members as well.
Aside from fields, properties and methods, Delphi classes can also hold shared constructors/destructors. A shared constructor is called when the application is started and allows you to initialize static fields or other stuff you might want to initialize from a static context in or possibly outside of the class. A shared destructor is called when your application is terminated, this allows you to clean up static resources and such. This is similar to the initialization and finalization clauses, but part of a class instead of the entire unit.
Static fields have to be added by adding the keywords “class var” as prefix. For properties you just add “class”. Static methods need to have prefix “class” and they can also take a “static;” at the end, this isn’t required for regular methods, but it is for mutators and accessors. Shared constructors/destructors also only need to have “class” added in front of them. Note that static contructors/destructors can take any name, even Create/Destroy, but i personally prefer the names CreateClass/DestroyClass.
Here’s an example that will show you all of these features:
program StaticTest;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes;
type
TTestClass = class
private
class var FStaticField: TStrings;
class function GetStaticField: string; static;
class procedure SetStaticField(const Value: string); static;
public
class property StaticField: string read GetStaticField write SetStaticField;
class constructor CreateClass;
class destructor DestroyClass;
end;
{ TTestClass }
class constructor TTestClass.CreateClass;
begin
FStaticField := TStringList.Create;
FStaticField.Text := 'Hello world!';
end;
class destructor TTestClass.DestroyClass;
begin
FStaticField.Free;
end;
class function TTestClass.GetStaticField: string;
begin
Result := FStaticField.Text;
end;
class procedure TTestClass.SetStaticField(const Value: string);
begin
FStaticField.Text := Value;
end;
begin
WriteLn(TTestClass.StaticField);
ReadLn; // Stop window from closing
end.
Read More