Обзор классов и объектов

Описание классов

Класс представляет собой составной тип, состоящий из полей (переменных), методов (процедур и функций) и свойств. Описание класса имеет вид:

type
  имя класса = class
    секция1 
    секция2 
       ...
  end;

Каждая секция имеет вид:

модификатор доступа 
   описания полей
   объявления или описания методов и описания свойств

Модификатор доступа в первой секции может отсутствовать, при этом подразумевается модификатор internal (видимость всюду внутри сборки).

Методы могут описываться как внутри, так и вне класса. При описании метода внутри класса его имя предваряется именем класса с последующей точкой. Например:

type
  Person = class
  private

    fName: string;
    fAge: integer;
  public
    constructor Create(Name: string; Age: integer);
    begin
      fName := Name;
      fAge := Age;
    end;
    procedure Print;
    property Name: string read fName;
    property Age: integer read fAge;
  end
;

procedure
Person.Print;
begin
  Writeln($'Имя: {Name} Возраст: {Age}');
end;

После слова class в скобках может быть указано имя класса-предка (см. Наследование), а также через запятую список поддерживаемых интерфейсов.

Перед словом class может быть указано ключевое слово sealed – в этом случае от класса запрещено наследовать.

Все описания и объявления внутри класса образуют тело класса. Поля и методы образуют интерфейс класса. Инициализаторы полей описаны здесь.

Классы могут описываться только на глобальном уровне. Локальные определения классов (т.е. определения в разделе описания подпрограмм) запрещены.

Переменные типа класс

В языке PascalABC.NET классы являются ссылочными типами. Это значит, что переменная типа класс хранит в действительности ссылку на объект.

Переменные типа класс называются объектами или экземплярами класса. Они инициализируются вызовом конструктора класса - специального метода, выделяющего память под объект класса и инициализирующего его поля:

var p: Person := new Person('Иванов',20);

После инициализации через переменную типа класс можно обращаться к публичным членам класса (полям, методам, свойствам), используя точечную нотацию:

Print(p.Name,p.Age);
p.Print;

Вывод переменной типа класс

По умолчанию процедура Write для переменной типа класс выводит содержимое её публичных полей и свойств в круглых скобках через запятую:

Write(p); // Иванов 20

Чтобы изменить это поведение, в классе следует переопределить виртуальный метод ToString класса Object - в этом случае именно он будет вызываться при выводе объекта.

Например:

type
  Person = class
    ...
    function
ToString: string; override;
    begin
      Result := $'Имя: {Name} Возраст: {Age}';
    end;
  end;
  ...
var p: Person := new Person('Иванов',20);
Writeln(p); // Имя: Иванов  Возраст: 20

Присваивание и передача в качестве параметров подпрограмм

Переменная типа класс является ссылкой и хранит ссылку на объект, создаваемый вызовом конструктора.

Как ссылка переменная типа класс может хранить значение nil:

p := nil;
...
if p = nil then ...

При присваивании переменных типа класс копируется только ссылка. После присваивания обе переменные типа класс будут ссылаться на один объект и совместно модифицировать его:

var p1,p2: Person;
...
p1 := new Person('Петров',20);
p2 := p1;
p1.IncAge;
p2.Print; // Имя: Петров  Возраст: 21

Сравнение на равенство

При сравнении переменных типа класс на равенство сравниваются ссылки, а не значения.

var p1 := new Person('Петров',20);
var p2 := new Person('Петров',20);
writeln(p1=p2); // False
p2 := p1;
writeln(p1=p2); // True

Это поведение можно изменить, перегрузив операцию = для класса.