Delphi. Properties

Свойства (properties), как и поля, являются атрибутами объекта. Поле это хранилище данных, свойство же обеспечивает доступ к этому хранилищу через Read / Write.

Синтаксис свойства следующий

property propertyName[indexes]: type index integerConstant specifiers;

propertyName – валидное название

indexes – это последовательность деклараций, объявленных через точку с запятой, опционально

type тип должен быть предопределен

index – integer константа, опционально

specifiers – это ключевые слова, такие как readwritestoreddefault (or nodefault), implements. Также, по крайней мере одно из ключевых слов read / write должно быть объявлено.

Свойства не всегда обязательно существуют в памяти, и поэтому их нельзя передавать как var параметры или через @. Они могут иметь только ключевое слово read, которое добывает значение из базы данных или генерирует случайное значение.

Пример объявления свойства

property Color: TColor read GetColor write SetColor;

При этом метод GetColor должен быть объявлен как

function GetColor: TColor;

А SetColor может быть объявлен одним из следующих способов

procedure SetColor(Value: TColor);
 procedure SetColor(const Value: TColor);

Ещё один пример

 type
    THeading = 0..359;
    TCompass = class(TControl)
      private
         FHeading: THeading;
         procedure SetHeading(Value: THeading);
      published
         property Heading: THeading read FHeading write SetHeading;
         ...
     end;

И вот как мы можем использовать свойства

if Compass.Heading = 180 then GoingSouth;
 Compass.Heading := 135;

или

if Compass.FHeading = 180 then GoingSouth;
 Compass.SetHeading(135);

Обновление значения могло бы быть таким

procedure TCompass.SetHeading(Value: THeading);
 begin
   if FHeading <> Value then
   begin
     FHeading := Value;
     Repaint;    // update user interface to reflect new value     
   end;
 end;

Индексные свойства

Это могут быть элементы списка, дочерние контролы контрола, пиксели битмапа.

Объявление их следующее

 property Objects[Index: Integer]: TObject read GetObject write SetObject;
 property Pixels[X, Y: Integer]: TColor read GetPixel write SetPixel;
 property Values[const Name: string]: string read GetValue write SetValue;

Get Set методы могли бы быть такими

function GetObject(Index: Integer): TObject;
 function GetPixel(X, Y: Integer): TColor;
 function GetValue(const Name: string): string;
 procedure SetObject(Index: Integer; Value: TObject);
 procedure SetPixel(X, Y: Integer; Value: TColor);
 procedure SetValue(const Name, Value: string);

И тогда, мы могли бы обращаться так

if Collection.Objects[0] = nil then Exit;
 Canvas.Pixels[10, 20] := clRed;
 Params.Values['PATH'] := 'C:\BIN';

Или так

if Collection.GetObject(0) = nil then Exit;
 Canvas.SetPixel(10, 20, clRed);
 Params.SetValue('PATH', 'C:\BIN');

Директива default

Мы можем написать так

type
    TStringArray = class
     public
        property Strings[Index: Integer]: string ...; default;
           ...
     end;

И тогда обращаться так

StringArray[i]
вместо
StringArray.Strings[i]

Ключевое слово index

Мы также можем написать так

type
    TRectangle = class
      private
        FCoordinates: array[0..3] of Longint;
        function GetCoordinate(Index: Integer): Longint;
        procedure SetCoordinate(Index: Integer; Value: Longint);
      public
        property Left: Longint index 0  read GetCoordinate 
                                        write SetCoordinate;
        property Top: Longint index 1   read GetCoordinate 
                                        write SetCoordinate;
        property Right: Longint index 2 read GetCoordinate
                                        write SetCoordinate;
        property Bottom: Longint index 3 read GetCoordinate
                                         write SetCoordinate;
        property Coordinates[Index: Integer]: Longint 
                                        read GetCoordinate
                                        write SetCoordinate;
        ...
    end;

И тогда, такой синтаксис

Rectangle.Right := Rectangle.Left + 100;

Соответствовал бы

Rectangle.SetCoordinate(2, Rectangle.GetCoordinate(0) + 100);

Storage 

Ключевые слова storeddefault, and nodefault не будут влиять на поведение программы, но влияют на то, будут ли published свойства сохранены в файлах форм.

Пример использования

property Name: TComponentName read FName write SetName stored False;

ключевое слово default может быть также использовано следующим образом

property Tag: Longint read FTag write FTag default 0;

Наследование свойств

Рассмотрим следующий пример

 type
    TAncestor = class
        ...
      protected
        property Size: Integer read FSize;
        property Text: string read GetText write SetText;
        property Color: TColor read FColor write SetColor stored False;
        ...
    end;
 
 type
 
    TDerived = class(TAncestor)
        ...
      protected
        property Size write SetSize;
      published
        property Text;
        property Color stored True default clBlue;
        ...
    end;

В потомках, мы можем переопределять видимость свойств. Из protected до public / published. Также, в потомке, мы добавили SetSize для Size и удалили read.

Аналогично, мы можем переопределить методы Read / Write

type
     TAncestor = class
       ...
       property Value: Integer read Method1 write Method2;
     end;
 
     TDescendant = class(TAncestor)
       ...
       property Value: Integer read Method3 write Method4;
     end;
 
  var MyObject: TAncestor;
       ...
      MyObject := TDescendant.Create;

Классовые свойства

Определяются следующим образом

 type
    TMyClass = class
      strict private
        class var         // Note fields must be declared as class fields
           FRed: Integer;
           FGreen: Integer;
           FBlue: Integer;
        public             // ends the class var block
           class property Red: Integer read FRed write FRed;
           class property Green: Integer read FGreen write FGreen;
           class property Blue: Integer read FBlue write FBlue;
    end;

А используются так

TMyClass.Red := 0;
 TMyClass.Blue := 0;
 TMyClass.Green := 0;
This entry was posted in Без рубрики. Bookmark the permalink.