Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прикладное программирование.doc
Скачиваний:
17
Добавлен:
25.12.2018
Размер:
683.01 Кб
Скачать

6.2. Объявления свойств-массивов

Объявление свойств-массивов имеет ряд особенностей как при их объ­явлении, так и при использовании.

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

Property <имя cвoucmвa>[[Const] <индекс1>:<тип шдекса>

[; [Coast] <индекс2>:<тип индекса>] ]: <тип данных>

[Read <метод чтения>]

[Write <метод записи>][; Default];

Примечания:

Индексы свойств-массивов оформляются аналогично параметрам процедур и функции, но только в квадратных скобках.

Идентификатор индекса свойства-массива может дополняться спе­цификатором Const.

Команда Default отделяется от других команд объявления свойства-массива точкой с запятой и должна быть последней.

Свойства-массивы могут иметь индексы любого стандартного типа.

Property FieldValues[Const FieldName: String]: Variant; Default;

// Свойство строкового типа компонентов Table, Query u TSoredProc, используемых для работы с базами данных. Есть строковый индекс и у TStrings. Values.

Function GetValue(Const Name: String): String;

Procedure SetValue(Const Name, Value: String);

Property Values[Const Name: String]; String Read GetValue Write SetValue;

Type

ArrStr=Array[1..7] Of String[10]; // Объявление типа - массива строк

TAnyClass=Class // Объявление нового класса

Private

FArr: ArrStr; // Поле-массив Function GetIntArr(iIndex: Integer): String; //Метод чтения Function GetStrArr(sIndex: String): Integer; //Метод чтения Public

Property Plnt[ilndex: Integer]: String Read GetIntArr;

Property PStr[sIndex: String]: Integer Read GetStrArr;

End;

Доступ к полю типа массив с помощью свойства со строковым индексом производится по значению строки. Фактически ищется индекс элемента мас­сива, значение которого равно строковому индексу свойства-массива.

Function TAnyCIass.GetStrArr(sIndex: String): Integer;

Var I: Byte;

Begin

Result:=-l;

For I:=l To 7 Do IfUpperCase(FArr[I])=UpperCase(sIndex) Then Result:=I;

End;

6.3. Раздел Read

Этот раздел в объявлении свойства указывает, как получать значения свойства. Может быть указано поле (прямой доступ) или метод чтения (косвенный доступ). В последнем случае, метод чтения должен быть функци­ей, тип которой совпадает с типом свойства.

Примечания:

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

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

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

Метод должен быть объявлен в определении класса до ссылки на него в объявлении свойства или в видимых разделах классов-предков. Рекомендуе­мое соглашение об именовании таких методов - начинать их со слова Get.

6.4. Раздел Write

Этот раздел в объявлении свойства указывает, как присваивать свойству новое значение. Может быть указано поле (прямой доступ) или метод записи (косвенный доступ). В последнем случае, метод записи должен быть проце­дурой с параметром, тип которого совпадает с типом свойства.

Примечания:

Для простых свойств - это единственный параметр метода записи.

Для векторных свойств, первым параметром метода записи должен быть индекс, а вторым - новые данные свойства.

Для свойств-массивов метод записи должен иметь на единицу больше параметров, чем размерность массива. Причем последний параметр - новые данные элементов массива, а остальные - тех же типов и в той же после­довательности, что и индексы массива.

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

Код реализации метода записи может включать процедуру Update, обновляющую представление компонента.

Метод записи должен быть объявлен в определении класса до ссылки на него в объявлении свойства или в видимых разделах классов-предков. Ре­комендуемое соглашение об именовании таких методов - начинать их со слова Set.

Если свойство типа массив использует прямой доступ к полю, то не­обходимо присваивать полю весь массив одновременно (обычно с помощью вспомогательной переменной-массива).

Некоторую особенность должен иметь раздел Write для объектных свойств:

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

• Метод Write должен производить проверку на Nil ссылки объекта, ко­торый предполагается присвоить с помощью свойства в поле объектного типа класса-обладателя свойства, например с помощью функции Assigned:

If Assigned( Value) Then FSomeObject.Assign(Value).

• Фактически следует не присваивать экземпляр класса свойству объ­ектного типа, а копировать значения его полей, иначе будет некорректная ра­бота с экземпляром при переприсвоении значений свойству объектного типа.

Свойства-объекты должны быть потомками класса TPersistent, если не­обходимо, чтобы их публикуемые свойства отображались в Инспекторе объ­ектов Delphi. В общем случае они могут быть потомками класса Tobject.

Рассмотрим упрощенный пример объявления и использования свойства-объекта, класс которого не является потомком класса TPersistent, поэтому не будет отображаться в инспекторе объектов. Последовательность создания свойства объекта следующая:

• Объявляем класс, который будет определять тип свойства-объекта:

TAnyClass=Class Private

FFId: String; // Поле класса

Public

Procedure Assign(0bj: TObject);

Property Fid: String Read FFId Write FFId; // Свойство класса

End;

• Объявляем класс, который будет включать свойство-объект:

TPropClass=Class Private

FProp: TAnyClass; // Поле свойства-объекта

Procedure SetPropObj(Obj: TAnyClass);

Public

Constructor Create;

Destructor Destroy; Override;

Property Prop: TAnyClass Read FProp Write SetPropObj; // Свойство

End;

• Создаем реализации всех методов, объявленных в обоих классах:

Procedure TAnyClass.Assign(Obj: TObject);

Begin

IfObj Ь TAnyClass Then Fld:=TAnyClass(Obj).Fld;

End;

Constructor TPropClass.Create;

Begin