Программное объявление классаКоманды DEFINE CLASS и ENDDEFINE образуют
программный блок, весь код внутри которого относится к определению класса. Класс
может быть определён в любом программном файле (с расширением .prg). Как до
команд определения класса, так и после могут следовать определения внешних
процедур и функций, а так же различные команды. Существует только одно
ограничение: класс не может быть определён внутри цикла или условного оператора.
DEFINE CLASS ClassName AS ParentClass [OF ClassLibrary] [[PROTECTED | HIDDEN] PropertyName1, PropertyName2 ...] [ADD OBJECT [PROTECTED] ObjectName AS ClassName [NOINIT] [WITH cPropertylist]] [[PROTECTED | HIDDEN] FUNCTION | PROCEDURE Name[_ACCESS |_ASSIGN] [([ParamName | ArrayName[]) | PARAMETERS | LPARAMETERS ParamName] cStatements [ENDFUNC | ENDPROC] ENDDEFINE Вы должны соблюдать описанную в листинге 11.7 последовательность предложений класса. Так, после команды DEFINE CLASS, в первую очередь следуют объявления свойств, затем команды ADD OBJECT, и, наконец, объявления методов. Команда DEFINE CLASSКоманда объявляет, что все последующие строки кода, вплоть до команды ENDDEFINE, составляют тело класса. DEFINE CLASS ClassName1 AS ParentClass [OF ClassLibrary] где:
Объявление свойств классаОбъявления свойств должны следовать непосредственно за командой объявления класса. [[PROTECTED | HIDDEN] PropertyName1, PropertyName2 ...] Ключевые слова PROTECTED и HIDDEN определяют
уровень видимости свойства. Уровень PROTECTED (защищённый) запрещает
доступ для считывания или изменения значений свойства извне определения класса.
Методы и события, определённые в классе или дочернем классе, могут обращаться к
защищенным свойствам; защищённые свойства и методы недоступны из включенных в
класс объектов.
Если вы хотите присвоить свойству значение по умолчанию, то делайте это в отдельной строке кода, например: PROTECTED Alpha Alpha = 10 Вы можете объявить массив как свойство класса, используя команду DIMENSION (для общедоступного свойства) или непосредственно в предложениях PROTECTED или HIDDEN: DEFINE CLASS myclass AS custom DIMENSION puArrayName[10,2] && Общедоступный массив puArrayName[1,1] = 100 ... и т.д. PROTECTED ArrayName[10] && Защищённый массив ArrayName[1] = 100 ... и т.д. ENDDEFINE Объявление методов классаОбъявления методов должны следовать после всех других объявлений класса. Метод объявляется либо как процедура, либо как функция, хотя любой метод может возвращать значение, то есть по сути является функцией, независимо от использованного при его объявлении ключевого слова. [PROTECTED | HIDDEN] FUNCTION | PROCEDURE Name [_ACCESS |_ASSIGN] [([ParamName | ArrayName[]) | PARAMETERS | LPARAMETERS ParamName ] cStatements [ENDFUNC | ENDPROC] Ключевые слова PROTECTED и HIDDEN определяют
уровень видимости метода (см. выше). Если вы не используете ни одно из этих
ключевых слов, то уровень видимости метода — PUBLIC. Параметр Name — это имя метода. Если используются ключевые слова _ACCESS или _ASSIGN, то Name — это имя свойства класса, запись и чтение которого контролируются соответствующими методами. Например, если вы хотите объявить метод _ASSIGN для свойства MyValue, то сделать это нужно так: PROCEDURE MyValue_ASSIGN Для указания списка получаемых методом параметров может использоваться один из следующих форматов: PROCEDURE MyMethod(Param1, Param2, …) или PROCEDURE MyMethod PARAMETERS Param1, Param2, … Первый формат равнозначен применению команды LPARAMETERS,
то есть все получаемые параметры имеют локальную область видимости. При
использовании второго формата получаемые параметры имеют область видимости
PRIVATE. PROCEDURE Alpha(taMyArray) EXTERNAL ARRAY taMyArray Если вы изменяете код метода, унаследованный от класса-родителя, то в объявлении такого метода нужно перечислить все получаемые им параметры в том же порядке, в каком они перечисляются в методе класса-родителя. Например, метод — обработчик события KeyPress получает два параметра: код нажатой клавиши и флаг, сообщающий, была при этом нажата одна из клавиш Ctrl, Shift или Alt. При объявлении этого метода в своём классе вы должны указать все получаемые им параметры: PROCEDURE KeyPress(nKeyCode, nShiftAltCtrl) Добавление объектов в класс-контейнерДля добавления объектов (управляющих элементов) в класс-контейнер применяется команда ADD OBJECT. ADD OBJECT [PROTECTED] ObjectName AS ClassName [NOINIT] [WITH cPropertylist] Параметры команды: ADD OBJECT [PROTECTED] ObjectName AS ClassName Определяет объект ObjectName, который наследуется от класса ClassName. В качестве класса-родителя может использоваться как базовый класс Visual FoxPro, так и пользовательский класс или ActiveX компонент. Необязательное ключевое слово PROTECTED предотвращает доступ для изменения свойств объекта из вне определяемого класса или подкласса. NOINIT Необязательное ключевое указывает, что метод Init добавляемого объекта не выполняется. WITH Определяет список свойств и их значений для объекта, которые вы добавляете в определение класса. cPropertyList Перечисленные через запятую операторы присваивания, в которых
свойствам объектов присваиваются значения «по умолчанию».
DEFINE CLASS MyForm AS Form Width = 300 Height = 80 ADD OBJECT Command1 as CommandButton WITH ; Left = 200, Top = 52, Width = 95, Height = 25, Caption = 'Закрыть' ENDDEFINE Вы можете устанавливать значения только для существующих
свойств добавляемого объекта. Visual FoxPro не контролирует правильность ввода
наименований свойств, поэтому, если вы ошибётесь в имени какого-либо свойства,
то это ошибка проявится только на этапе выполнения приложения. PROCEDURE Command1.Click Строки_кода_метода ENDPROC В листинге 11.9. приведен пример программного создания формы.
PUBLIC oForm oForm = CREATEOBJECT('MyForm') && Создать объект из класса MyForm oForm.Show() && Показать форму на экране * * Объявление класса формы * DEFINE CLASS MyForm AS Form Width = 300 Height = 80 * * Добавляем в класс формы командную кнопку * ADD OBJECT Command1 as CommandButton WITH ; Left = 200, Top = 52, Width = 95, Height = 25, Caption = 'Закрыть' PROCEDURE Click() = MESSAGEBOX('Вы щёлкнули по мне!') ENDPROC * * Добавляем код в метод Click командной кнопки * PROCEDURE Command1.Click() thisform.release ENDPROC ENDDEFINE Первые три строки кода — это команды, которые создают форму и выводят её на экран. Из объявления класса видим, что форма будет иметь размеры 300
на 80 пикселей; так как значения для свойств Top и Left формы не
устанавливаются, то используются их значения по умолчанию (нули).
Методы Init, Destroy и ErrorВсе пользовательские классы наследуют свойства и методы класса-родителя. Здесь вы познакомитесь с назначением и применением наследуемых методов Init, Destroy и Error, которые вы так же можете переопределять. Метод InitМетод Init выполняется после инициализации объекта — экземпляра класса. К моменту выполнения этого метода объект создан, а так же созданы все размещаемые на нём командой ADD OBJECT управляющие элементы. Особенностью метода Init является возможность получать параметры, передаваемые ему функциями CREATEOBJECT() и NEWOBJECT(), а для динамически создаваемых управляющих элементов — методами AddObject и NewObject объектов-контейнеров. Список получаемых параметров вы можете перечислить как в строке с именем метода, так и используя команду LPARAMETERS: PROCEDURE Init(Parameter1 [, Parameter2, ets… ]) или PROCEDURE Init LPARAMETER Parameter1 [, Parameter2, ets… ] Если вы хотите использовать переданные в метод параметры, то
вы должны сохранить их в свойствах класса. RETURN = .F. то объект разрушатся, объектная ссылка не создаётся. Метод DestroyЭтот метод всегда выполняется перед разрушением объекта. При вызове этого метода все вложенные объекты и свойства существуют. Метод ErrorМетод Error вызывается, когда при выполнении кода в одном из методов класса возникает ошибка. Метод получает следующие параметры:
Если вы не перегружаете этот метод, то при возникновении ошибки во время выполнении одного из методов класса будет выведено окно со следующим сообщением (рис.11.28). Рис.11.29. Результат выполнения метода Error класса Использование метода Error позволяет получить подробную информацию о месте, причине и характере ошибки. Всё зависит только от написанного вами кода. Подключение программных модулей к приложениюЕсли вы объявляете классы в программных модулях (файлах типа .prg), то вы должны использовать команду SET PROCEDURE TO имя_файла [ ADDITIVE ] для указания Visual FoxPro на необходимость просматривать эти
файлы при выполнении функции (метода), создающей объект. Управление временем жизни объектовКаждый объект — экземпляр класса связан либо с переменной, выполняющей роль
объектной ссылки (указателя на объект), либо с объектом-контейнером. oObj1 = CREATEOCJECT('MyClass') oObj2 = oObj1 RELEASE oObj1 && После уничтожения этой переменной объект ещё существует RELEASE oObj2 && Теперь объект уничтожен Если существует внешняя ссылка на вложенный объект объекта-контейнера, то, если
при уничтожении объекта эта ссылка будет существовать, это приведёт к тому, что
объект не сможет уничтожить вложенный объект, и, следовательно, и он, и не
уничтоженный вложенный объект останутся в памяти, что приведёт к утечке памяти
и, возможно, ошибкам времени выполнения. Obj = CREATEOBJECT('ClassName') Obj = NULL && или, например, Obj = .F. Вторая строка кода уничтожает объект — экземпляр класса ClassName. Obj = CREATEOBJECT('ClassName1') Obj = CREATEOBJECT('ClassName2') Вторая строка кода уничтожает объект — экземпляр класса ClassName1. Размещаемые в объектах-контейнерах объекты — управляющие элементы уничтожаются
после выполнения метода Destroy контейнера, то есть на момент вызова этого
метода все управляющие элементы ещё существуют. Для принудительного удаления
объекта из объекта-контейнера используется его метод RemoveObject.
|