Свойства-массивы

   
На этом шаге мы рассмотрим использование свойств-массивов.

   
На первый взгляд свойства-массивы отличаются от простых свойств приблизительно также, как переменные типа "массив" от переменных простых типов, то есть
наличием индекса. Однако, способ описания и использования индексов в свойствах-массивах имеет достаточно большие различия по сравнению с индексацией обычных массивов.
Остановимся отдельно на отличиях свойств-массивов как от простых свойств, так и от простых массивов.

   
Отличия свойств-массивов от простых свойств:

  • Главной особенностью объявления является наличие списка индексных параметров. Обратим внимание, не индексов, а именно параметров, определяющих индексы,
    которые записываются подобно формальным параметрам процедур с указанием типа. При описании списка индексных параметров используются не круглые,
    квадратные скобки. В этом проявляется отличие свойств-массивов как от простых свойств, так и от простых массивов.
  • В описании спецификаторов доступа read и write могут быть указаны только идентификаторы методов. Прямое использование идентификатора поля запрещено.
  • Метод, указанный в спецификаторе чтения, должен быть функцией, у которой количество, типы и порядок расположения параметров соответствуют описанию индексных параметров свойства.
    Тип результата, возвращаемого этой функцией должен совпадать с типом свойства.
  • Метод, указанный в спецификаторе записи, должен быть процедурой, у которой количество, типы и порядок расположения начальных параметров соответствуют описанию индексных параметров
    свойства. Кроме того, список параметров процедуры должен иметь один дополнительный параметр такого же типа, как у свойства, для передачи нового значения. Этот параметр может быть или параметром-значением, или параметром-константой.
  • Свойства-массивы не могут быть опубликованными (published).
  •    
    Отличия свойств-массивов от переменных типа "массив":

  • Обращение к свойству-массиву как к единому целому не допускается. Разрешены действия только с его отдельными элементами.
  • Тип индексов у свойств-массивов может быть любым, а не только порядковым.
  •    
    Покажем использование свойств-массивов на следующем примере.

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Memo2: TMemo;
        Label1: TLabel;
        Label2: TLabel;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
      TVectorClass = class
      private
        FVector : array [1..10] of Word;
      protected
        function GetVector (Index : Integer) : Word;
        procedure SetVector (Index : Integer; Value : Word);
        procedure AddToVectorElem (Index : Integer; Value : Word);
      public
        property Elements [Index : Integer] : Word
            read GetVector
            write SetVector;    default; { свойство по умолчанию }
        property AddToElement [Index : Integer] : Word
            write AddToVectorElem;
      end;
    
    
    var
      Form1: TForm1;
      MyVector : TVectorClass;
    
    implementation
    
    {$R *.dfm}
    
    function TVectorClass.GetVector(Index : Integer) : Word;
    begin
      Result := FVector [Index];
    end;
    
    procedure TVectorClass.SetVector (Index : Integer; Value : Word);
    begin
      FVector [Index] := Value;
    end;
    
    procedure TVectorClass.AddToVectorElem(Index : Integer; Value : Word);
    begin
      FVector [Index] := FVector [Index] + Value;
    end;
    
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      i : Integer;
      S : String;
    begin
      MyVector := TVectorClass.Create;
      for i := 1 to 10 do
        MyVector[i] := i; { Имя свойства Elements может быть }
        {опущено, поскольку это свойство будет принято по умолчанию}
      for i := 1 to 10 do
      begin
        Str(MyVector.Elements[i], S);
        Form1.Memo1.Lines.Add(S);
      end;
      for i := 1 to 10 do
        MyVector.AddToElement[i] := 5;  { Имя свойства }
        { AddToElement всегда должно быть указано полностью }
      for i := 1 to 10 do
      begin
        Str (MyVector[i], S);
        Form1.Memo2.Lines.Add(S);
      end;
      MyVector.Free;
    end;
    
    end.
    

    Текст этого примера можно взять здесь.

       
    Результат:


    Рис.1. Результат работы приложения

       
    Обратите внимание, что, несмотря на все перечисленные отличия, обращение к элементам свойства-массива выполняется так же, как и к элементам обычного массива.

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

    • как к любому другому свойству с помощью полного квалифицируемого имени MyVector.Elements[i];
    • как к свойству, принятому по умолчанию, с указанием только имени объекта и индекса MyVector[i].

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

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
      TRow  ='a'..'h' ;
      TColumn  = 1..8;
      TCheckersBoard =   class
      private
        FBoard : array [TRow,TColumn] of  Char;
      protected
        function GetChecker (Row: TRow; Col: TColumn):Char;
        procedure  SetChecker (Row: TRow; Col: TColumn; const Value: Char);
      public
        property Board [Row: TRow; Col: TColumn]: Char
          read GetChecker write SetChecker; default;
      end;
    
    var
      Form1: TForm1;
      MyBoard : TCheckersBoard;
    
    
    implementation
    
    {$R *.dfm}
    
    function TCheckersBoard.GetChecker (Row : TRow; Col :TColumn) : Char;
    begin
      Result := FBoard [Row,Col];
    end;
    
    procedure TCheckersBoard.SetChecker (Row : TRow; Col : TColumn; 
               const Value : Char) ;
    begin
      FBoard [Row, Col] :=Value;
    end;
    
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      i : TRow;
      j : TColumn;
      s : String;
      k,l : Integer;
    begin
      MyBoard := TCheckersBoard.Create;
      for i := 'a' to 'h' do
        for j :=1 to 8 do
           MyBoard [i,j]:=' ';
      Memo1.Lines.Clear;
      k:=0;
      for i := 'a' to 'h' do
      begin
        if Ord(i) mod 2 = 1 then
        begin
          MyBoard [i,1]:='Б';
          MyBoard [i,3]:='Б';
          MyBoard [i,7]:='Ч';
        end
        else
        begin
          MyBoard [i,2]:='Б';
          MyBoard [i,6]:='Ч';
          MyBoard [i,8]:='Ч';
        end;
      end;
      for j :=1 to 8 do
      begin
        S:='';
        for i := 'a' to 'h' do
             S:=S+MyBoard [i,j];
        Memo1.Lines.Add(S);
      end;
    end;
    
    end.
    

    Текст этого примера можно взять здесь.

       
    Результат:


    Рис.2. Результат работы приложения

       
    На следующем шаге мы рассмотрим свойства со спецификатором index.



    Вы можете оставить комментарий, или Трекбэк с вашего сайта.

    Оставить комментарий