Классы и записи
Классы и записи объединяют связанные данные и методы в одном типе. Данные, хранящиеся в объекте класса или записи, называются полями.
В PascalABC.NET для описания составных данных обычно используются классы. Класс — ссылочный тип, а запись — значимый тип: при присваивании класс копирует ссылку на объект, а запись — само значение.
Классы
Классы объединяют данные и методы для описания объектов программы.
Описание класса и создание объекта
Тип класса описывается с помощью class в секции type. Экземпляр класса создаётся с помощью new, а к его полям обращаются через точку.
type
Person = class
Name: string;
Age: integer;
end;
begin
var p := new Person;
p.Name := 'Анна';
p.Age := 21;
Println(p.Name, p.Age);
end.
Результат:
Анна 21
Конструктор класса
Конструктор позволяет задать начальные значения полей при создании объекта.
Переменная Self в конструкторе обозначает текущий объект и позволяет отличать его поля от одноимённых параметров конструктора.
type
Person = class
Name: string;
Age: integer;
constructor(name: string; age: integer);
begin
Self.Name := name;
Self.Age := age;
end;
end;
begin
var p := new Person('Анна',21);
Println(p.Name, p.Age);
end.
Результат:
Анна 21
Метод класса
Метод класса может обращаться к полям текущего объекта.
type
Person = class
Name: string;
Age: integer;
constructor(name: string; age: integer);
begin
Self.Name := name;
Self.Age := age;
end;
procedure PrintInfo;
begin
Println(Name, Age);
end;
end;
begin
var p := new Person('Анна',21);
p.PrintInfo;
end.
Результат:
Анна 21
Автокласс
Модификатор auto автоматически создаёт конструктор и позволяет компактно описывать классы, предназначенные прежде всего для хранения данных.
Стандартная процедура Print выводит для переменной автокласса все поля:
type
Person = auto class
Name: string;
Age: integer;
end;
begin
var p := new Person('Иванов',18);
Print(p);
end.
Результат:
(Иванов,18)
Присваивание переменных классов
При присваивании переменной класса копируется ссылка на объект, а не сам объект. Поэтому две переменные могут ссылаться на один объект.
type
Person = auto class
Name: string;
Age: integer;
end;
begin
var p1 := new Person('Анна',21);
var p2 := p1;
p2.Age := 22; // p1 и p2 ссылаются на один объект
Println(p1.Age);
end.
Результат:
22
Сравнение объектов класса
По умолчанию объекты класса сравниваются по ссылкам: две переменные равны, если они ссылаются на один и тот же объект.
type
Person = auto class
Name: string;
Age: integer;
end;
begin
var p1 := new Person('Анна',21);
var p2 := p1;
var p3 := new Person('Анна',21);
Println(p1 = p2);
Println(p1 = p3);
end.
Результат:
True
False
Значение nil
Переменной класса можно присвоить nil; в этом случае она не ссылается ни на какой объект.
type
Person = class
Name: string;
Age: integer;
end;
begin
var p: Person := nil;
Println(p = nil);
p := new Person;
Println(p = nil);
end.
Результат:
True
False
Записи
Записи объединяют несколько связанных полей в один составной тип данных. Запись является значимым типом. Для переменной типа запись не требуется вызов конструктора - память выделяется при описании переменной.
Описание типа и создание записи
Тип записи описывается с помощью record в секции type
type
Person = record
Name: string;
Age: integer;
end;
begin
var p: Person;
p.Name := 'Анна';
p.Age := 21;
Println(p);
end.
Результат:
(Анна,21)
Метод записи
Запись, как и класс, может содержать методы.
type
Point = record
X, Y: real;
// Расстояние до начала координат
function Distance := Sqrt(X * X + Y * Y);
end;
begin
var p: Point;
p.X := 3;
p.Y := 4;
Println(p.Distance);
end.
Присваивание записей
При присваивании записи копируется её значение. Поэтому изменение одной переменной не изменяет другую.
type
Person = record
Name: string;
Age: integer;
end;
begin
var p1: Person;
p1.Name := 'Анна';
p1.Age := 21;
var p2 := p1;
p2.Age := 22;
Println(p1.Age);
Println(p2.Age);
end.
Результат:
21
22
Сравнение записей
Записи одного типа можно сравнивать на равенство. При сравнении сопоставляются значения их полей.
type
Person = record
Name: string;
Age: integer;
end;
begin
var p1, p2: Person;
p1.Name := 'Анна';
p1.Age := 21;
p2.Name := 'Анна';
p2.Age := 21;
Println(p1 = p2);
p2.Age := 22;
Println(p1 = p2);
end.
Результат:
True
False