На этом шаге мы рассмотрим использование свойств-массивов.
На первый взгляд свойства-массивы отличаются от простых свойств приблизительно также, как переменные типа "массив" от переменных простых типов, то есть наличием индекса. Однако, способ описания и использования индексов в свойствах-массивах имеет достаточно большие различия по сравнению с индексацией обычных массивов. Остановимся отдельно на отличиях свойств-массивов как от простых свойств, так и от простых массивов.
Отличия свойств-массивов от простых свойств:
Отличия свойств-массивов от переменных типа "массив":
Покажем использование свойств-массивов на следующем примере.
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 возможны два способа обращения:
Также как и массивы, свойства-массивы могут быть многоиндексными. Списки индексных параметров таких свойств и формальных параметров их методов доступа должны иметь соответствующее размерности число индексов. В следующем примере, в котором буквами Б и Ч моделируется исходная позиция шашек на доске, показано использование двумерного свойства.
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.