суббота, 19 мая 2012 г.

Классы и записи - помощники

Перевод раздела Class and Record Helpers из справочной системы Delphi

О классах и записях - помощниках

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


Классы-помощники и записи-помощники дают возможность расширить тип, но они не могут рассматриваться как инструмент разработки нового кода. Работая с новым кодом вы должны всегда полагаться на обычное наследование и реализацию интерфейсов.


Синтаксис помощника

Синтаксис объявления класса-помощника:

type
   identifierName = class|record helper [(ancestor list)] for TypeIdentifierName
     memberList
   end;

ancestor list - опционален.

Помощник не может содержать объявления полей, но позволяет объявлять поля класса.

Правила области видимости и синтаксис memberList идентичны объявлению обычного класса или записи.

Вы можете объявить несколько помощников и связать их с одним типом, но видимым будет только один помощник, определенный в ближайшей области видимости. Область видимости класса-помощника или записи-помощника определяется обычным для Delphi образом (например, справа налево в секции uses модуля).


Применение помощников

Следующий пример показывает объявление класса-помощника (записи-помощники работают аналогичным образом):

type
    TMyClass = class
       procedure MyProc;
       function  MyFunc: Integer;
    end;
 
    ...
 
    procedure TMyClass.MyProc;
    var X: Integer;
    begin
       X := MyFunc;
    end;
 
    function TMyClass.MyFunc: Integer;
    begin
        ...
    end;
 
 ...
 
 type
    TMyClassHelper = class helper for TMyClass
      procedure HelloWorld;
      function MyFunc: Integer;
    end;
 
    ...
 
    procedure TMyClassHelper.HelloWorld;
    begin
       Writeln(Self.ClassName); // Self ссылается на тип TMyClass, не на TMyClassHelper
    end;
 
    function TMyClassHelper.MyFunc: Integer;
    begin
      ...
    end;
 
 ...
 
 var
   X: TMyClass;
 begin
   X := TMyClass.Create;
   X.MyProc;    // Вызывает TMyClass.MyProc
   X.HelloWorld; // Вызывает TMyClassHelper.HelloWorld
   X.MyFunc;    // Вызывает TMyClassHelper.MyFunc

Следует учесть, что вызывается функция MyFunc класса-помощника, поскольку тип класса-помощника имеет преимущество перед исходным типом класса.

1 комментарий:

  1. Фразу
    >Помощник не может объявлять экземпляров данных, но поля типа класс разрешены.
    очень сложно понять. Весьма неочевидно, что нельзя заводить var, но можно class var

    ОтветитьУдалить