Статические классы, поля, методы, свойства и конструкторы

В классе можно объявить так называемые статические поля, свойства и методы. Они не принадлежат конкретному экземпляру класса, а связаны с классом. Для их вызова используется точечная нотация, причем, перед точкой используется не имя объекта, а имя класса. Чтобы поле или свойство или метод сделать статическим, перед его именем следует указать ключевое слово static. При описании статических свойств в секциях read и write можно указывать только статические поля или методы.

Например, определим для класса Person количество созданных объектов этого класса как статическое поле и организуем доступ к этому полю на чтение с помощью статической функции. После каждого вызова конструктора значение статического поля будет увеличиваться на 1:

type
  Person = class
  private
    name: string;
    age: integer;
    static cnt: integer := 0;
  public
    static property
Coun: integer read cnt;
    constructor (n: string; a: integer);
    begin
      cnt += 1;
      name := n;
      age := a;
    end;
    static function Count: integer;
    begin
      Result := cnt;
    end;

  end;

begin
  var p: Person := new Person('
Иванов',20);
  var p1: Person := new Person('
Петров',18);
  Writeln(Person.Count); //
обращение к классовому методу Count
end.

В отличие от статических полей и методов, обычные поля и методы называются экземплярными. Из обычных методов можно обращаться к экземплярным и статическим полям, но из статических методов можно обращаться только к статическим полям.

Аналогично можно определить также статический конструктор, предназначенный для автоматической инициализации классовых полей. Статический конструктор описывается с ключевым словом static и гарантированно вызывается перед вызовом любого статического метода и созданием первого объекта этого класса.

Например, определим в классе Person статическое поле - массив объектов типа Person - и инициализируем его в статическом конструкторе. Потом указанный массив можно использовать в реализации статической функции RandomPerson, возвращающей случайный объект типа Person:

type
  Person = class
  private
    static arr: array of Person; 
    name: string;
    age: integer;
  public
    static constructor;
    begin
      SetLength(arr,3);
      arr[0] := new Person('Иванов',20);
      arr[1] := new Person('Петрова',19);
      arr[2] := new Person('Попов',35);
    end;
    //...
    static function RandomPerson: Person;
    begin
      Result := arr[Random(3)];
    end;
  end;
const cnt = 10;
begin
  var a := new Person[cnt];
  for var i:=0
to a.Length-1 do
    a[i] := Person.RandomPerson;
end.

Класс также можно описывать как статический:

type
  MyStatic = static class
    static
Pi: real := 3.14;
    static
function Pi2 := Pi * Pi;
  end;

В этом случает все его методы, поля, свойства и конструкторы должны быть статическими. Запрещается создавать экземпляры статических классов. Кроме того, от статических классов нельзя наследовать, статический класс не может быть предком и статическим классом нельзя инстанцировать обобщенный класс.

Для совместимости с Delphi статические члены класса можно также объявлять с ключевым словом class, которое в этом контексте является синонимом static:

type
  MyStatic = static class
   
class Pi: real := 3.14;
   
class function Pi2 := Pi * Pi;
  end;