
- •Программирование и алгоритмические языки. Курс за третий семестр.
- •Введение в объектно-ориентированное программирование (ооп)
- •Идеологический обзор
- •Базовые принципы ооп
- •Наследование имён. Наследование значений.
- •Коллизия
- •Что такое имя процедуры?
- •Ооп как оперирование типами
- •Именование типов в c# Тип данных «класс»
- •Конструкторы и деструкторы
- •И нкапсуляция данных
- •Наследование (краткое введение)
- •Наследование реализации как уточнение семантики типа
- •Пополнение и переопределение методов Отношение пополнения интерфейса
- •Открытие реализации для проектирования классов - опция protected
- •Полиморфизм Полиморфизм как уточнение семантики типа переменной
- •Динамические методы как поддержка полиморфизма- опции static, virtual, override
- •Событийное программирование Обработка событий
- •Идея: Когда что-то вставляется, срабатывает некоторый предикат. Например, после вызывается команда проверки, каскадного удаления или какая-нибудь другая команда. Генераторы и приёмники сообщений
- •Событийное программирование нужно:
- •Событийный стиль в процедурном программировании - управление данными (на примере)
- •Событийное программирование в c# (delegate, event)
- •Введение в компонентное программирование
- •Объекты, реализующие интерфейсы
- •Частный случай общей проблемы взаимодействия программного обеспечения разных производителей на уровне исполняемого кода
- •Базовый интерфейс компонент
- •Проблема множественности иерархий
- •Коллизия имён
- •Коллизия реализации
- •«Симметричное» решение – агрегаты (декартовы произведения классов)
- •Множественное наследование
- •«Асимметричное» решение - именованные интерфейсы
- •Основные отличия интерфейса и абстрактного класса
- •Наследование интерфейса (компонентный подход)
- •Обработка исключений в ооп
- •Определение и генерация исключений в c#
- •Выбрасывание исключений
- •Захват исключения
- •Блок finally
- •Коды программ
Событийный стиль в процедурном программировании - управление данными (на примере)
Пример (животные):
Задача: Описывается вызов движения блохи. Как только блоха начинает движение, все динозавры начинают кричать: «Ай-яй-яй». Нужно заметить, что явного вызова того, чтобы динозавры кричали, нет (но этот вызов где-то прошит). Событием здесь является то, что блоха движется, а динозавры кричат.
Замечание:
Блоха- отправитель сообщений, а TRex-ы – слушатели.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Animals
{
class cAnimal
{
.
.
.
}//class cAnimal
//класс "cDinosaur" наследник класса "сAnimal"
public class cDinosaur : cAnimal
{
.
.
.
} //class cDinosaur
class cTRex : cDinosaur
{
.
.
.
//обработка событий - слушатель (listener) события FleaJumpEvent
private cFlea FleaJumpSender; // Flea To Listen To- поле, в котором хранится ссылка на блоху, а FleaJumpSender-Отправитель
public void SetFleaJumpSender(cFlea x) // получает ссылку на эту блоху
{
FleaJumpSender = x; // запоминание источника события
//Итак, блоха нужна для того, чтобы получить лист (список слушателей), который при ней хранится.
FleaJumpSender.FleaJumpEventList += new cFlea.FleaJumpEventHandler(TRexFleaJumpEventHandler);// добавление в список ссылки на свой обработчик
// new- создаётся новая копия описанной переменной функционального типа. После новое значение этого типа добавляется в список.
// += -это бинарное присваивание (т.е. имя списка и в левой, и в правой частях присваивания)
// аналогично осуществляется отказ от подписки "-="
}
public void TRexFleaJumpEventHandler(cFlea Sender)
{
Console.WriteLine(GetName() + "afraid of" + Sender.GetName() + "jumping");
}
} // class cTRex
// класс "Flea" наследник класса "cAnimal"
class cFlea : cAnimal //производный класс "Блоха"
{
.
.
.
public override void Move() // описание метода "двигаться" для блох
{
Console.WriteLine(GetName() + "jumps");
OnFleaJump(); // кратный вызов
}
.
.
.
}
}
Событийное программирование в c# (delegate, event)
Delegate - функциональный тип, к которому относятся любые функции, принимающие на вход параметр типа блоха (т.е. cFlea Sender) и возвращающие функции.
Таким образом, к этому типу относятся все функции с определённым списком параметров.
Event - событие- объявление переменной списка ссылок ранее объявленного типа
class cFlea
{
.
.
.
// обработка событий-источник/ sender(Отправитель)
// организация обработки события FleaJumpEvent
public delegate void FleaJumpEventHandler(cFlea Sender); // типизированая ссылка на функцию- обработчик- заголовок
//-объявление функционального типа с именем FleaJumpEventHandler- типизированная ссылка на функцию, но не на тип данных
EventHandler- пользовательское соглашение- обработчик событий,
FleaJump-прыжок блохи
public event FleaJumpEventHandler FleaJumpEventList; // связь имени события с его обработчиками (реализация- список ссылок на обработчики)
//список называется FleaJumpEventList, содержит он ссылки типа FleaJumpEventHandler
//кратный вызов - применение объявленного списка к нужному аргументу (обработчиков)
protected virtual void OnFleaJump() //protected, т.к. события не вызываются извне
//OnFleaJump- по прыжку блохи-стандартное соглашение для методов такого назначения
{ // проверка на пустоту списка
if (FleaJumpEventList != null) FleaJumpEventList(this); // если список не является пустым, то применяем его (список) к this (т.е. блоха в качестве сообщения пересылает ссылку на себя), передавая значения полей
// Таким образом, не функция применяется к аргументу, а список функциональных ссылок (т.е. по ссылкам "дёргаются" функции, которые применяются поочерёдно к списку аргументов)
}
//теперь везде, где прыгает блоха, вызывается метод OnFleaJump
//OnFleaJump нужно вызвать в методе Move
} //class cFlea
class cProgram
{
static void Main()
{
cDinosaur Dino = new cDinosaur("Dino");
cFlea Bug = new cFlea("Bug");
Bug.Attacks(Dino); // полиморфный вызов- неявное уточнение типа cAnimal
Console.WriteLine("______________________");
//аналогично
// Dino.cAnimal x;
// x=Dino; // уточнение типа не требует явного преобразования типа
// Bug. Attacks(x);
// отследи вызов последней реализации
cTRex Rex = new cTRex("Rex");
Bug.Attacks(Rex);
Console.WriteLine("______________________");
//обработка событий
cTRex AnotherRex = new cTRex("Another Rex");
Rex.SetFleaJumpSender(Bug); //вызывается метод set, в котором говорится о том, чтобы Rex слушал Bug
AnotherRex.SetFleaJumpSender(Bug); //AnotherRex слушал Bug
Bug.Move(); //движение блохи (в этом методе есть OnFleaJump, который вызывает методы всех динозавров)
Console.ReadKey(); //задержка
}
}
}
Производится распечатка имени динозавра и демонстрация того, что динозавр боится прыжков блохи (выдаётся имя конкретной блохи).
Таким образом, public delegate void FleaJumpEventHandler(cFlea Sender); -объявление функционального типа (указатель на все функции данного типа, аргументами (параметрами) которых служит блоха)- не является заголовком функции.
delegate void FleaJumpEventHandler(cFlea Sender) понимается так:
-заводится новый тип для создания списка ссылок такого типа
-именуется