9.1 Описание

На верх  Назад  Вперёд

Расширенные записи эквивалентны объектам и классам (меньше): они являются записями, которые имеют методы и свойства. Как и объекты, если запись определена в качестве переменной она выделяются в стеке. Им не нужно иметь конструктор. Расширенные записи имеют ряд ограничений в сравнению с объектами и классами, они не поддерживают наследование и полиморфизм. Невозможно создать потомка записи от записи (хотя она может быть усилена с помощью записей-помошникав (helpers), больше об этом в главе 10.1 Определение (о помощников-записях)).

Почему же тогда введены расширенные записи? Они были введены Delphi 2005 для поддержки одной из особенностей, вносимых NET. Delphi изменил старый стиль TP объектов, и добавил в .NET расширенные записи. Free Pascal стремится быть Delphi совместим, таким образом расширенные записи разрешаются в Free Pascal, только в режиме совместимости с Delphi.

Если расширенные записи необходимы, нужно использовать режим ObjFPC:

{$mode objfpc}

{$modeswitch advancedrecords}

Совместимость не является единственной причиной введения расширенных записей. Есть некоторые практические причины для использования методов или свойств в записях:

1.Это больше соответствует объектно-ориентированному подходу к программированию: тип (расширенные записи) содержит методы, которые работают с ним.

2.В отличие от процедурного подхода, собрав все операции, которые работают с записью в самой записи, позволяет IDE, чтобы показать доступные методы записи, когда предоставляет варианты завершения кода.

Расширенная запись объявляется сходно с объявлением объекта или класса:


Тип расширенная запись

901


Ограничения в сравнении с классами или объектами видны из диаграммы синтаксиса:

Записи не наследуются (inheritance).

Раздела published не существует.

Не определены конструктор и/или деструктор.

Методы класса (если их можно так назвать) требуют ключевого слова static.

Методы не могут быть virtual (виртуальными) или abstract (абстрактные) - это следствие того, что нет наследования.

За исключением этого определение напоминает определение класса или объекта.

Ниже приведены несколько примеров допустимых определений расширенных записей:

TTest1 = record

a : integer;

function Test(aRecurse: Boolean): Integer;

end;

 

TTest2 = record

private

A,b : integer;

public

procedure setA(AValue : integer);

property SafeA : Integer Read A Write SetA;

end;

 

TTest3 = packed record

private

fA,fb : byte;

procedure setA(AValue : Integer);

function geta : integer;

public

property A : Integer Read GetA Write SetA;

end;

 

TTest4 = record

private

  a : Integer;

protected

  function getp : integer;

public

  b : string;

  procedure setp (aValue : integer);

  property p : integer read Getp Write SetP;

public

case x : integer of

  1 : (Q : string);

  2 : (S : String);

end;

Обратите внимание, что можно указать видимость для членов записи. Это очень полезно, при создании интерфейса к библиотеке C: реальные поля могут быть объявлены скрытыми, а более pascal подобные свойства могут быть открыты, и действовать как фактические поля. Определение записи TTest3 показывает, что директива packed (упакована) тоже может использоваться в расширенных записях. Расширенные записи имеют структуру памяти такую-же, как и обычные записи: методы и свойства не являются частью структуры записей в памяти.

Определение записи TTest4 в приведенном выше примере показывает, что расширенная запись может иметь и вариантную часть. Как и в случае с обычной записью, вариантная часть должна быть последней. Она не может содержать методы.