Свойства-массивы. Свойство класса по умолчанию. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Свойства-массивы. Свойство класса по умолчанию.



http://delphikingdom.ru/lyceum/seminar.asp?id=6

Свойства-массивы (array properties).

Свойства­-массивы – это индексированные свойства. Они могут представлять такие сущности, как элементы списков, управляющие элементы, принадлежащие некоторому родительскому, пикселы изображения и т.д.

Объявление свойства-массива включает список параметров, который определяет имена и типы индексов, например:

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;

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

TShortSet = set of 0..9;

MyClass = class

private

F1: integer;

Function PNameRead(i1: string; i2: single; i3:TObject; i4:ShortSet): string;

public

property PName[ i1: string;

i2: single;

i3: TObject;

i4: TShortSet]:string read PNameRead;

end;

В частности, свойства-массивы не могут быть опубликованными.

Для свойств-массивов спецификаторы доступа должны быть методами, а не полями. Метод в спецификаторе read должен быть функцией, число, порядок и тип параметров которой должны точно соответствовать списку индексов свойства. Возвращаемое функцией значение должно иметь, разумеется, тип свойства.

Метод в спецификаторе write должен быть процедурой, число, порядок и тип параметров которой должны точно соответствовать списку индексов свойства. К списку параметров необходимо также добавить один параметр значение или константу того же типа, что и тип свойства.

Например, методы доступа для описанных выше свойств­-массивов должны быть описаны так:

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:\DELPHI\BIN';

соответствуют

if Collection.GetObject(0) = nil then Exit;

Canvas.SetPixel(10, 20, clRed);

Params.SetValue('PATH', 'C:\DELPHI\BIN');

Определение свойства-массива может сопровождаться директивой default, что делает свойство свойством по умолчанию. Например, если класс описан как

type

TStringArray = class

public

property Strings[Index: Integer]: string...; default;

end;

доступ к его свойству по умолчанию может быть получен путем простого индексирования имени объекта objec t [inde x], что эквивалентно objec t .propert y [inde x]. Для приведенного выше примера выражение StringArray.Strings[7] может быть сокращено до StringArray[7].

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

Спецификатор Index (Index specifiers).

Этот спецификатор предоставляет возможность нескольким свойствам использовать один и тот же метод, возвращающий разные значения (одного типа). Спецификатор Index сопровождается целой константой из диапазона
-2147483647..2147483647. Если свойство имеет спецификатор 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;

Метод доступа для свойства со спецификатором index должен иметь дополнительный параметр – значение целого типа. Для метода (функции) read это должен быть последний параметр, а для метода write это должен быть предпоследний параметр, т.е. параметр, предшествующий параметру, задающему значение свойства. Когда программа осуществляет доступ к значению свойства, значение (константа) index автоматически передается методу.

С учетом приведенного выше описания код

var

Rectangle: TRectangle;

Rectangle.Right:= Rectangle.Left + 100;

соответствует такому вызову метода

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

Спецификаторы сохранения (Storage specifiers).(дифолт=свойства по умолчанию)

Так называются необязательные директивы store d, defaul t и nodefault. Они не оказывают никакого влияния на работу программы, однако управляют тем, как Delphi поддерживает информацию о типах времени выполнения (RTTI). Конкретно, эти спецификаторы определяют, сохраняет ли Delphi значения опубликованных свойств в файлах форм (.dfm).

Вслед за директивой stored необходимо указать True, False, имя поля булевского типа или имя функции без параметров, которая возвращает значение булевского типа. Например

property Name: TComponentName read FName write SetName stored False;

Если для свойства не указана директива stored, она трактуется как имеющая значение True.

Вслед за директивой default должна следовать константа того же типа, что и тип свойства. Например

property Tag: Longint read FTag write FTag default 0;

Для перекрытия унаследованного значения по умолчанию без задания нового надо указать директиву NoDefault. Директивы default и nodefault поддерживаются для свойств только порядкового типа, а также множественного типа диапазона значений 0..31. Если свойство не имеет директив default или nodefaul t, оно трактуется как имеющее директиву nodefault.

Когда Delphi сохраняет состояние компонента, она проверяет обсуждаемые спецификаторы для опубликованных свойств. Если текущее значение свойства отличается от его значения по умолчанию (или если значение по умолчанию не задано) и спецификатор stored имеет значение True, то значение свойства сохраняется. В противном случае – нет.

Отметим, что спецификаторы сохранения не поддерживаются для свойств-массивов. Для свойств-массивов директива default трактуется иначе.

Перекрытие и повторное описание свойств (Property overrides and redeclarations).

Описание свойства, в котором не указан его тип, называется перекрытием свойства. Перекрытие свойства позволяет изменить унаследованную видимость свойства или спецификаторы.

Простейший способ перекрытия состоит в указании только зарезервированного слова property и имени свойства. Этот прием используется для изменения видимости свойства (property’s visibility). Например, если в родительском классе свойство описано как protected, производный класс может переобъявить его в секции public или published.

Повторное описание свойства может включать директивы rea d, writ e, store d, defaul t и nodefault, и любая из них перекрывает соответствующую унаследованную. Перекрытие (повторное описание) может изменить унаследованный спецификатор доступа, содержать отсутствующий спецификатор или увеличить видимость свойства, однако оно не может удалить спецификатор доступа или уменьшить видимость свойства. Повторное описание может также включать директиву implements, которая добавляет свойство в список интерфейсов без удаления унаследованных.

Следующие описания иллюстрируют перекрытие описаний свойств.

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;

Перекрытие свойства Size добавляет спецификатор write, делая свойство доступным и по записи. Перекрытие свойств Text и Color изменяет их видимость, а для свойства Color задает также и значение по умолчанию.

Повторное объявление свойства с указанием его типа скрывает унаследованное свойство, а не перекрывает его. Это значит, что новое свойство создается с тем же именем, что и "доставшееся по наследству". Вследствие этого любое повторное описание свойства должно быть семантически полным и должно включать по меньшей мере один спецификатор доступа.

Независимо от того, перекрывается ли свойство или скрывается в производном классе, поиск свойства объекта имеет статический характер. Это значит, что для идентификации объекта, которому принадлежит свойство, используется информация времени компиляции. Например, пусть есть такой фрагмент программы:

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;

Теперь получение или изменение значения свойства MyObject.Value будет выполняться с использованием методов Method1 и Method 2, хотя MyObject является экземпляром класса TDescendan t. Вместе с тем возможно использование приведения типа MyObject к типу TDescendan t для получения доступа к свойствам и соответствующим методам производного класса.

Создание собственного редактора свойства (property editor).

Несмотря на то, что инспектор объектов включает редактирование по умолчанию для всех типов свойств, можно реализовать свой собственный редактор свойства. Можно зарегистрировать редактор только для одного свойства своего собственного компонента или для всех свойств определенного типа.

Принципиально редактор свойств может иметь один из двух режимов работы (или оба):

отображение и редактирование значения свойства как строки символов: создание диалогового окна, которое может предоставлять другой сособ редактирования свойства.

Разработка редактора свойства выполняется в следующей последовательности:

1 Deriving a property-editor class

2 Editing the property as text

3 Editing the property as a whole

4 Specifying editor attributes

5 Registering the property editor

 

 



Поделиться:


Последнее изменение этой страницы: 2017-02-21; просмотров: 231; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.188.40.207 (0.017 с.)