Лекция 7(События).pptx
- Количество слайдов: 15
Интерфейсы. Делегаты. События Лекция 7 1
Понятие интерфейса Интерфейс – «крайний» случай абстрактного класса. В нем задается набор абстрактных методов, свойств и событий, которые должны быть реализованы в производных классах. Синтаксис интерфейса аналогичен синтаксису класса: interface class имя-инт [ : public имя-базов-инт [ , public имя-базов-инт ]. . . ] { объявление функций , свойств и событий }; Интерфейс не может содержать конструкторы, деструкторы, поля. 5
Пример создания интерфейса interface class Iprim { property int P; void M(); }; ref class А: public Iprim { private: int x; public: virtual void M( ) {Console: : Write. Line ("Метод работает"); } property int P { virtual void set (int V) {x= V; } virtual int get ( ) {return x; } } }; void main ( ){ А^ p. A = gcnew А(); // Создать объект класса А p. A->P = 77; // Установить свойство P Console: : Write. Line ( p. A -> P. To. String ()); p. A->M(); // Вызвать метод } 6
Интерфейсы и абстрактные классы Если набор действий нужно реализовать разными способами для некоторой иерархии классов, то лучше задать этот набор в виде виртуальных методов абстрактного базового класса иерархии. То, что работает в пределах иерархии одинакового, следует полностью определить в базовом классе. Интерфейсы обычно используются для задания общих свойств объектов разных иерархий. 7
Делегаты Делегат – это класс, объект которого сохраняет, а затем вызывает одну или несколько функций с одинаковой сигнатурой. Как любой класс, делегат – это тип данных. Чтобы воспользоваться делегатом, нужно создать его экземпляр и добавить в него необходимые функции. Вызов объекта делегата приводит к выполнению инкапсулированных в нём функций. Можно передать объект делегата в качестве параметра функции. Делегаты используются для поддержки событий, а также как самостоятельная конструкция языка. 8
Описание делегата определяет сигнатуру функций, которые могут быть вызваны с его помощью: delegate тип имя ([параметры]) где: тип – тип возвращаемого значения делегируемой функции; имя – имя класса делегата; параметры - список типов параметров делегируемой функции. Это описание компилятор преобразует в класс, у которого есть конструктор и 3 метода. Пример описания делегата: delegate void Del(String ^name); Такое объявление и реализация делегата предполагает делегирование функции любого имени, но точно с заданными списком параметров и типом возвращаемого значения. 9
Создание объекта делегата Перед применением делегата необходимо объявить дескриптор на него, а затем с помощью оператора gcnew создать объект делегата. Мы можем добавить в делегат обычную глобальную функцию, а также открытый метод управляемого класса (перед описанием класса стоит ключевое слово ref). Синтаксис зависит от типа функции: // глобальная функция My. Function Del ^ X = gcnew Del(&My. Function); // статический метод St. Metod класса My. Class Del ^ X = gcnew Del (&My. Class: : St. Metod); // нестатический метод My. Metod класса My. Class ^ C = gcnew My. Class(); Del ^ X = gcnew Del(C, &My. Class: : My. Metod); 10
Добавление функций Для добавления к объекту новых функций используется перегруженный оператор «+» , для удаления – «-» . Синтаксис снова зависит от типа функции: // глобальная функция My. Function 1 X = X+ gcnew Del(&My. Function 1); X += gcnew Del(&My. Function 1); X = X- gcnew Del(&My. Function 1); X -= gcnew Del(&My. Function 1); // статический метод St. Metod 1 класса My. Class X += gcnew Del (&My. Class: : St. Metod 1); X -= gcnew Del (&My. Class: : St. Metod 1); // нестатический метод My. Metod 1 класса My. Class ^ C = gcnew My. Class(); X += gcnew Del(C, &My. Class: : My. Metod 1); X += gcnew Del(C, &My. Class: : My. Metod 2); X -= gcnew Del(C, &My. Class: : My. Metod 1); 11
Вызов функций с помощью делегата Вызов последовательности функций с помощью делегата выглядит, как обычное обращение к функции: X( «Пример"); При вызове нужно учитывать, что: сигнатура функций должна точно соответствовать делегату; функции выполняются в том порядке, в котором они добавлялись; каждому методу передается один набор параметров; если параметр передается по ссылке, изменения параметра в одном методе отразятся на его значении при вызове следующего метода. 12
Пример использования делегата как параметра функции #include "stdafx. h" using namespace System; delegate void del (void); // Объявление делегата del ref class My. Cl { // Класс с функцией R() для делегата del public: void R(){Console: : Write. Line ("R"); } }; void M (del ^d) {d( ); } // Глобальная функция для делегата del void main () { My. Cl ^ P= gcnew My. Cl ( ); //Создать объект класса My. Cl del ^p. Del = gcnew del(P, &My. Cl: : R); //Создать объект делегата M (p. Del); // Функция M() вызовет функцию My. Cl: : R } 13
События – это элемент класса, позволяющий ему посылать другим объектам уведомления об изменении своего состояния. При этом для объектов, являющихся наблюдателями события, активизируются методы-обработчики этого события. Обработчики должны быть зарегистрированы в объектеисточнике события. Применительно к событиям введена следующая терминология. Объект, генерирующий (firing) события, называют источником (source), а объект, получающий событие, называют приёмником (sink). Функции приёмника, реагирующие на событие, называют обработчиками (handlers) события. Часто используются и другие термины. Объект, генерирующий события, называют издателем (publisher). Говорят, что издатель публикует события, на которые должны подписаться подписчики (subscribers) - объекты, обработчики которых реагируют на события издателя. Подписка на событие заключается в привязке к событию требуемого обработчика. 14
Создание события События построены на основе делегатов: с помощью делегатов вызываются методы-обработчики событий. Создание события включает следующие шаги: описание делегата, задающего сигнатуру обработчиков событий; описание события; описание метода (методов), инициирующих событие. Например: delegate void Del (); // Делегат события ref class Gen. Ev { // Класс объекта-источника события public: event Del^ p. Ev; //Дескриптор события // Генерировать событие ! void Generate. Ev( ) {p. Ev ( ) ; } }; 15
Обработка событий выполняется в классах-получателях. Для этого в них описываются методы-обработчики событий, сигнатура которых соответствует типу делегата : ref class Use. Ev { // Класс объекта-приёмника события public: static void Handler. Ev ( ) // Функция-обработчик {Console: : Write. Line ("Объект получил событие"); } }; Каждый объект (не класс!), желающий получить сообщение, должен зарегистрировать в объекте-отправителе этот метод: Gen. Ev ^p. Gen. Ev= gcnew Gen. Ev; // источник события Use. Ev ^p. Use. Ev= gcnew Use. Ev; // приёмник события // Добавить обработчик p. Gen. Ev -> p. Ev += gcnew Del (Use. Ev: : Handler. Ev); 16
Пример использования события delegate void Del (); // Делегат события ref class Gen. Ev { // Класс объекта-источника события public: event Del^ p. Ev; //Дескриптор события void Generate. Ev( ) {p. Ev ( ) ; } // Генерировать событие ! }; ref class Use. Ev { // Класс объекта-приёмника события public: static void Handler. Ev ( ) // Функция-обработчик события {Console: : Write. Line ("Объект получил событие"); } }; void main ( ){ Gen. Ev ^p. Gen. Ev= gcnew Gen. Ev; // источник события Use. Ev ^p. Use. Ev= gcnew Use. Ev; // приёмник события // Добавить обработчик p. Gen. Ev -> p. Ev += gcnew Del (Use. Ev: : Handler. Ev); p. Gen. Ev ->Generate. Ev(); // Сгенерировать событие } 17
Правила оформления событий в среде. NET При программировании событий рекомендуется: в имени обработчика события использовать слово Handler; обработчики событий должны иметь возвращаемое значение void; делегат события и, конечно, обработчик должен иметь следующий список параметров: (Object ^sender, Event. Args ^args) где sender (^sender) - дескриптор на объект-источник события, args (^args) - дескриптор на объект класса, порождённого из класса Event. Args, который содержит открытые (public) данные или свойства, связанные с событием. Класс Event. Args наследует класс Object и содержит единственное свойство Empty, значение false которого указывает о наличии данных, а true – об их отсутствии. Если делегат не использует информацию о событии, то можно не описывать делегата и собственный тип аргументов, а обойтись стандартным классом делегата System. Event. Handler. 18
Лекция 7(События).pptx