Свойства классов, синтаксис объявления, типы данных свойств

Свойства классов (property) — это атрибут формы или другого компонента, который влияет либо на визуальное поведение, либо на операции, выполняемые формой или компонентами. Фактически свойство — это просто имя, связанное с полем напрямую или методами записи и/или чтения и наиболее видимая часть класса.

При использовании в этом точном техническом значении, термин обозначает расширение концепции поля данных. Свойство является элементом определения класса и обеспечивает специальную защиту связанных с ним данных, поддерживая их автоматическую настраиваемую обработку при просмотре и изменении значений. Другими словами, свойство не являются только данными, которые присваиваются и используются; присвоение и/или использование этих данных может привести к особым побочным эффектам. Это один из часто используемых вариантов реализации инкапсуляции.

Объявление свойств

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

Property <имя свойства>: <тип данных>
[Index <целое число>}
[Read <поле свойства\метод чтения>]
[Write <поле свойства\метод записи>}
[Stored <логическое выражение>]
[Default <значение по умолчанию>|NoDefault]
[DispID <целое число>] [Implements <список интерфейсов>

Примечания:
• Delphi позволяет объявлять свойства следующих типов:
• простые типы, включая целые и вещественные числа, например Width, Height, символьные, перечислимые (например цвет формы, компонентов), логические (False, True) и диапазоны;
• строковые, например имена компонентов (Name), заголовки (Caption), значения (Text):
множества, например Borderlcons (biSystemMenu, biMinimize, biMaximize, biHelp). Раз-мер публикуемых (Published) свойств типа множество ограничен 32 элементами (0..31). С большим числом элементов можно объявить свойство в разделе Public;
— массивы, включая многомерные, например Lines (TStrings). Нельзя объявлять такие свойства в разделе Published. Массивы обычно имеют встроенные редакторы для изменения значений;
— указатели;
• Объявление свойства никогда не приводит к резервированию памяти для хранения значений свойства, поскольку экземпляр класса хранит значение свойства в одном из соответствующих своих полей.
• Свойства должны объявляться после объявления полей, можно вперемежку с методами. Главное, чтобы упоминаемые в разделах Read и Write методы были описаны ранее.
• Поля и/или методы доступа могут быть унаследованными, но видимыми потомком.
• Свойства, как и поля, могут использоваться в качестве аргументов процедур и функций, а также участвовать в выражениях, например логических, математических. Нельзя, однако, передавать их по ссылке (как Var параметр),
• Свойство должно иметь хотя бы один из разделов Read или Write. Если раздел Read отсутствует, то свойство доступно только для записи, например, для хранения пароля, а, если отсутствует раздел Write, то свойство годится только для чтения и его нельзя модифицировать.
• Если потребности в специальных методах нет, то для доступа к полям можно вместо имен методов использовать имена полей. Чаще всего так делают для раздела Read.
• Методы чтения и записи рекомендуется объявлять в разделе Protected, чтобы их нельзя было неосторожно изменить, а также виртуальными или динамическими, чтобы была возможность переопределить их в потомках. Методы, однако, не должны быть абстрактными (Abstract) или перегружаемыми (Overload).
• Если в разделах Read и Write указаны методы, то типы данных поля и свойства могут не совпадать. В этом случае соответствующие преобразования типов должны производится в методах чтения и записи.
• Свойства, как и другие составляющие класса, наследуются потомками.

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

В простейшем случае может использоваться прямой доступ к полю. Чаще всего прямой доступ используется при операциях чтения значения поля.

Type
TAnyComponent=Class(TConiponent) // Объявление нового класса
Private
FCount: Integer; // Используется для хранения свойства
Procedure SetCount(Value: Integer); // Объявление метода записи
Public
Property Count: Integer Read FCount Write SetCount; //Объявление свойства
End;

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

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

Раздел Read

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

Примечания:
• Для простых свойств метод чтения должен быть функцией, возвращающей значение свойства.
• Для векторных свойств, метод чтения должен быть функцией, имеющей один индексный параметр и возвращающей значение свойства.
• Для свойств-массивов метод чтения должен быть функцией с таким же количеством и типом параметров, что и индексы в объявлении свойства-массива, и это функция должна возвращать значение свойства.
• Метод должен быть объявлен в определении класса до ссылки на него в объявлении свойства или в видимых разделах классов-предков. Рекомендуемое соглашение об именовании таких методов — начинать их со слова Get.

Раздел Write

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

Примечания:
• Для простых свойств — это единственный параметр метода записи.
• Для векторных свойств, первым параметром метода записи должен быть индекс, а вторым — новые данные свойства.
• Для свойств-массивов метод записи должен иметь на единицу больше параметров, чем размерность массива. Причем последний параметр — новые данные элементов массива, а остальные — тех же типов и в той же последовательности, что и индексы массива.
• В любом случае параметр с данными должен передаваться либо по значению, либо как Const.
• Метод записи должен быть объявлен в определении класса до ссылки на него в объявлении свойства или в видимых разделах классов-предков. Рекомендуемое соглашение об именовании таких методов — начинать их со слова Set.
• Если свойство типа массив использует прямой доступ к полю, то необходимо присваивать полю весь массив одновременно (обычно с помощью вспомогательной переменной-массива).

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

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

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

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

Команды Default, NoDefault и Stored

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

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

Примечания:
• Этот раздел можно указывать только для порядковых типов данных и множества. Допустим он и для данных типа указатель с единственным значением Nil, поэтому фактически нецелесообразен.
• Пункт со значением по умолчанию сам по себе не устанавливает значение свойства — ответственность за это лежит на программисте, и необходимо в конструкторе класса явно написать оператор, присваивающий свойству предусмотренное по умолчанию значение.
• Команда Default лишь информирует транслятор о том, каким значением будет инициализировано свойство. Это позволяет при считывании и записи в файлы формы и компонентов узнавать, нужно ли записывать в файл *.Dfm значение свойства. Если текущее значение свойства такое же, как в команде Default, то его можно не записывать, уменьшая таким образом размер файла.
• Для свойств-массивов команда Default объявляет соответствующее свойство-массив свойством по умолчанию, что позволяет упростить доступ к элементам такого массива. При обращении к такому свойству его имя можно не упоминать, а индексы в квадратных скобках указывать у имени объекта. Очевидно, что только одно свойство-массив класса и его потомков может иметь такую команду. В классах-потомках нельзя отметить эту команду.
AnyObject[2]:=’Bтоpoй способ — при указании свойства Default’;

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

в) Команда Stored используется для того, чтобы указать на необходимость сохранения значения свойства. За командой Stored могут стоять либо ключевые слова: True False, либо указана <переменная\метод-функция с логическим результатов. Часто используется для свойств, объявляемых в разделе Published и всегда сохраняемых в ресурсном файле.

Команда Index

Команда Index используется в связи с методами доступа к нескольким свойствам. Если несколько свойств имеют идентичные методы доступа для чтения и/или записи, то выбор свойства внутри таких методов может быть сделан с помощью оператора Case и значения цело-численного параметра команды Index.

Примечания:
• Эта команда указывается первой в списке команд объявления свойств.
• Методы доступа к свойству, имеющему раздел Index должны иметь дополнительный параметр, объявленный как Integer. Для метода чтения этот параметр должен быть последним в списке параметров функции, а для метода записи этот параметр должен быть предпоследним в списке параметров процедуры — предшествовать параметру, определяющему значение свойства.

Команды DispID и Implements

а) Команда DispID используется для присвоения свойству значения Dispatch ГО, которое применяется в автоматизации OLE. Это целочисленное значение обычно используется при объявлении свойств Dispatch интерфейсов. Эта команда может быть указана только у свойства, объявляемого в разделе Automated класса. Более подробно эта команда будет рассмотрена далее.

б) Команда Implements используется при делегировании полномочий интерфейсов свойству класса


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





Статистика

Рейтинг@Mail.ru