- •Объектно-ориентированное программирование
- •Часть 1 классы и объекты
- •Введение
- •1. Классы и объекты
- •Var aLine: tLine;
- •Var aColorLine: tColorLine;
- •2. Методы
- •2.1. Методы-функции и методы-процедуры
- •2.2. Конструкторы и деструкторы
- •Inherited Create;
- •Var TmpFrm: tForm;
- •Var Mem: tMemo;
- •2.3. Классовые процедуры и функции
- •Var s: String;
- •2.4. Скрытый Self
- •3. Видимость компонентов класса
- •4. Наследование
- •4.1. Основные понятия
- •4.2. Наследование полей
- •4.3. Поведение методов при наследовании
- •Var SomeObject: t1;
- •Virtual;
- •Virtual; Abstract;
- •4.4. Иерархия классов
- •4.5. Rtti
- •4.6. Проверка типа
- •4.7. Приведение типа
- •4.8. Указатели на класс
- •Var ObjRef: tObjRef;
- •Implementation
- •X, y, w, h: Integer): tControl;
- •5. Полиморфизм
- •6. Свойства (properties)
- •6.1. Объявление свойств
- •6.2. Объявления свойств-массивов
- •Var I: Byte;
- •6.3. Раздел Read
- •6.4. Раздел Write
- •Inherited Create;
- •Inherited Destroy;
- •6.5. Команды Default, NoDefault и Stored
- •6.6. Команда Index
- •Var aYear, aMonth, aDay: Word;
- •Var aYear, aMonth, aDay: Word;
- •6.7. Команды DispId и Implements
- •6.8. Переопределение свойств при наследовании
- •7. События (events)
- •7.1. Объявление событий
- •IfAssigned(fOnMouseMove) Then fOnMouseMove(Self, Shift, X, y);
- •Vk_return: NumMemo.DoNumStr(l);
- •Vk_return: PostMessage(NumMemo.Handle, wm_user1,1, 0);
- •7.2. Обработчики событий
- •7.3. Делегирование событий
- •Var Objl: tIstClass;
- •7.4. Переопределение стандартных событий
- •Var NewBtn: tNewButton;
6. Свойства (properties)
Свойство (property) - это атрибут формы или другого компонента, который влияет либо на визуальное поведение, либо на операции, выполняемые формой или компонентами. Например, свойство Visible определяет, является ли компонент видимым. Аналогично свойство Enable определяет, доступен или нет управляющий элемент. Фактически свойство - это просто имя, связанное с полем напрямую или методами записи и/или чтения и наиболее видимая часть класса.
При использовании в этом точном техническом значении, термин обозначает расширение концепции поля данных. Свойство является элементом определения класса и обеспечивает специальную защиту связанных с ним данных, поддерживая их автоматическую настраиваемую обработку при просмотре и изменении значений. Другими словами, свойство не являются только данными, которые присваиваются и используются; присвоение и/или использование этих данных может привести к особым побочным эффектам. Это один из часто используемых вариантов реализации инкапсуляции.
Свойства более удобны, чем поля. Свойства компонентов доступны во время разработки, поэтому изменяя их значения, можно настраивать программу уже во время ее разработки. При этом производится перерисовка компонентов и результаты настройки доступны пользователю также во время разработки.
6.1. Объявление свойств
Синтаксис объявления свойства класса:
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. Массивы обычно имеют встроенные редакторы для изменения значений;
• указатели;
• объекты, включая интерфейсные типы, например TFont. Объекты обычно имеют встроенные редакторы для изменения значений. Свойства-объекты должны происходить от класса TPersistenf.
• Объявление свойства никогда не приводит к резервированию памяти для хранения значений свойства, поскольку экземпляр класса хранит значение свойства в одном из соответствующих своих полей.
• Свойства должны объявляться после объявления полей, можно вперемежку с методами. Главное, чтобы упоминаемые в разделах Read и Write методы были описаны ранее.
• Поля и/или методы доступа могут быть унаследованными, но видимыми потомком.
• Свойства, как и поля, могут использоваться в качестве аргументов процедур и функций, а также участвовать в выражениях, например логических, математических. Нельзя, однако, передавать их по ссылке (как Var параметр), а также использовать с оператором @.
• Свойство должно иметь хотя бы один из разделов Read или Write. Если раздел Read отсутствует, то свойство доступно только для записи, например, для хранения пароля, а, если отсутствует раздел Write, то свойство годится только для чтения и его нельзя модифицировать.
• Если потребности в специальных методах нет, то для доступа к полям можно вместо имен методов использовать имена полей. Чаще всего так делают для раздела Read.
• Методы чтения и записи рекомендуется объявлять в разделе Protected, чтобы их нельзя было неосторожно изменить, а также виртуальными или динамическими, чтобы была возможность переопределить их в потомках. Методы, однако, не должны быть абстрактными (Abstract) или перегружаемыми (Overload).
• Если в разделах Read и Write указаны методы, то типы данных поля и свойства могут не совпадать. В этом случае соответствующие преобразования типов должны производится в методах чтения и записи.
• Свойства, как и другие составляющие класса, наследуются потомками.
• Свойства, объявляемые в разделе Automated класса, могут иметь только разделы Read, Write и DispID.
Type
TAnyClass=Class(TComponent) // Объявление нового класса
Private
FCount: Integer; // Поле для хранения значения свойства
Protected
Function GetCount: Integer; // Объявление метода чтения
Procedure SetCount(Value: Integer); // Объявление метода записи
Public
Property Count: Integer Read GetCount Write SetCount Default. 1; // Свойство
End;
Var AnyObject: TAnyClass; // Объявление переменной
Function TAnyClassGetCount: Integer; // Реализация метода чтения
Begin
GetCount:'=FCount; // Присвоение значения
End;
Procedure TAnyClass.SetCount(Value: Integer); // Реализация метода записи
Begin
If Value>=0 Then FCount:=Value Else FCount:=0; // С проверкой на значение
End;
Доступ к значению свойства Count осуществляется через вызовы методов GetCount и SetCount. Однако обращаться напрямую к этим методам нет необходимости, поскольку в программе достаточно написать:
AnyObject.Count:=123;
AVariable:=AnyObject.Count;
Компилятор оттранслирует операторы присвоения в вызовы методов чтения и записи. Если используется прямой доступ к полю, то значения поля будут доступны с помощью операторов присвоения. Таким образом, внешне свойство выглядит в точности как обычное поле, но за всяким обращением к нему могут стоять нужные вам действия. Например, если имеется объект геометрическая фигура и его свойству "цвет" присваивается значение "белый", то произойдет немедленная перерисовка объекта в цвет, соответствующий значению свойства.
Важное значение имеют свойства при разработке компонентов. Разработчик может менять реализацию методов, а для пользователей все остается по старому.
В простейшем случае может использоваться прямой доступ к полю. Чаще всего прямой доступ используется при операциях чтения значения поля.
Type
TAnyComponent=Class(TConiponent) // Объявление нового класса
Private
FCount: Integer; // Используется для хранения свойства
Procedure SetCount(Value: Integer); // Объявление метода записи
Public
Property Count: Integer Read FCount Write SetCount; // Объявление свойства
End;
В Delphi не предусмотрены ограничения на то, как хранить значения свойства. Однако компоненты Delphi придерживаются правила, заключающегося в том, что значение свойства хранится в поле, которые обычно объявляются в разделе Private класса.
Производные компоненты должны использовать наследуемые свойства. Они не нуждаются в прямом доступе к внутреннему хранению данных.