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

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

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

type
  Person = class
  private
    name: string;
    age: integer;
    class cnt: integer := 0;
  public
    constructor (n: string; a: integer);
    begin
      cnt += 1;
      name := n;
      age := a;
    end;
    class 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.

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

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

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

type
  Person = class
  private
    class arr: array of Person; 
    name: string;
    age: integer;
  public
    class constructor;
    begin
      SetLength(arr,3);
      arr[0] := new Person('Иванов',20);
      arr[1] := new Person('Петрова',19);
      arr[2] := new Person('Попов',35);
    end;
    //...
    class 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.