Светофор односторонний: светит только водителю, пешеход ориентируется на водителя.
Классы: Driver (водитель), Pedestrian (пешеход), TrafficLight (светофор) и Program (тестирующий)
В классе TrafficLight возникает два чередующихся статических события:
Поле: имя водителя.
Обработчик события Event1: Выводит сообщение: Имя водителя, еду. Проехавший водитель отписывается от обоих событий.
Обработчик события Event2: Выводит сообщение: Имя водителя, стою.
Поле: имя пешехода.
Обработчик события Event1: Выводит сообщение: Имя пешехода, стою.
Обработчик события Event2: Выводит сообщение: Имя пешехода, иду. Прошедший пешеход отписывается от обоих событий.
Обработчик события Event1: Зеленым цветом выводит сообщение: Горит зеленый свет.
Обработчик события Event2: Красным цветом выводит сообщение: Горит красный свет.
Метод с параметром (целое число), по очереди генерирующий или событие Event1 (если число четное) или событие Event2 (если число нечетное)
Порядок написания кода программы:
Подготовим эти три простейших класса:
Класс TrafficLight и его методы:
ChangeLight (int i) – метод, в котором будет меняться свет. Этот метод событие генерирует, но мы его пока не описываем. Ставим заглушку.
Red() –обработчик события горит красный
Green() – обработчик события горит зеленый
Два других класса (с именами Driver и Pedestrian) тоже должны реагировать на возникновение события
В классе Driver:
Поле name, два конструктора, и два обработчика событий:
В классе Pedestrian:
Поле name, два конструктора, и два обработчика событий:
В классе TrafficLight, в котором возникает событие, конструируем его.
Сначала определяем по методам, которые должны сработать при возникновении события, их сигнатуру.
Наше событие будет обрабатываться шестью методами, по два в каждом классе. Мы должны посмотреть сигнатуры этих методов (то есть посмотреть заголовки), и составить на основе этих сигнатур делегаты.
У наших обработчиков сигнатуры одинаковые: нет выходного значения и нет параметров. Поэтому делегат будет один.
Определяем делегат (назовем его Hadler). Опишем на его основе два события Event1 и Event2. Далее генерируем события в коде:
Событие создано. Методы, которые вызовут это событие, определены по сигнатурам и на их основе создан делегат. Событие, в свою очередь, создано на основе делегата.
Теперь покажем, какие методы в классах должны вызываться в ответ на событие.
Вернемся в точку входа программы main и создадим объект класса TrafficLight. Подпишем этот объект на оба события.
Теперь нужно подписать на эти события пешеходов и водителей. Их может быть несколько. Каждый из них это объект с другим именем. Поэтому создавать их, и подписывать их на события, нужно в цикле. Пусть их будет 5. Получим:
В процессе написания программы у нас не должно быть ни одной ошибки. Если ошибка возникла, нужно сразу выяснять причину.
Выполним отработку:
Наблюдаем странную ситуацию: Водитель 1, который должен был уехать на зеленый свет, остался на нашем перекрестке. То же самое с пешеходами. Пешеходы никуда не уходят, водители никуда не уезжают.
Это происходит потому, что каждый из них по-прежнему подписан на оба события. А нам нужно, чтобы:
То есть это должно происходить в их классах. Для пешехода в методе Go класса Pedestrian. Для водителя в методе Ride класса Driver.
Но в этих классах у нас нет объекта svet светофор, от которого нужно отписываться. Поэтому придется в этом случае (далеко не всегда это нужно) события сделать статическими. Это даст нам возможность, при подписке и отписке не указывать имя объекта, а указывать имя класса.
В классе TrafficLight, опишем события, как статические.
Сразу появится много ошибок в тестирующем классе. Потому что наше событие мы присоединяли к объекту, а не к классу. А статическое событие не присоединяют к объекту. Поэтому сразу исправим эти ошибки в классе Program. Везде svet.Event1 поменяем его на TrafficLight.Event1, а svet.Event2 поменяем его на TrafficLight.Event2.
От статических событий можно отписаться в любом месте проекта.
Нам нужно, чтобы пешеход перешел дорогу и ушел, то есть не реагировал на светофор. То есть сразу после перехода улицы, в методе Go в классе Pedestrian нужно отписаться от событий связанных со светофором:
Нам нужно, чтобы водитель пересек перекресток и уехал, то есть не реагировал на светофор. То есть сразу после пересечения перекрестка, в методе Ride в классе Driver нужно отписаться от событий связанных со светофором:
Результат:
Классы: Car (машина), Parking (стоянка)- генерируются два события, Sequrity (охранник)-обработчик события , Police (полиция) обработчики двух событий и Program (тестирующий)
В классе Parking возникает два статических события:
Отработка 1: возникло только событие NotPlaces.
Отработка 2: возникло событие NotPlaces и 3 раза возникло событие SignalTriggered.
Поле: номер машины
Свойство для чтения поля номер машины
Конструктор с параметром.
Поле: имя
Свойства для чтения поля имя.
Конструктор с параметрoм.
Обработчик события NotPlaces:
Поле: имя
Свойствo для чтения поля имя.
Конструктор с параметрами.
Обработчик события NotPlaces:
Обработчик события SignalTriggered:
События возникают в этом классе. Поэтому здесь описываются и события и соответствующие им делегаты. События статические, так как происходят в этом классе, а отписываемся от них в других классах.
Делегатов два, так как у их обработчиков разная сигнатура: один тип без параметров и без возвращаемого значения, второй с целым параметром и без возвращаемого значения.
Поля: адрес стоянки, количество мест, List < Car > - список машин, логическая переменная: есть ли места на стоянке, счетчик срабатываний сигнализации.
Свойство для чтения поля – есть ли места.
Конструктор с параметрами.
Метод, в котором возникает событие NotPlaces и событие SignalTriggered
Создадим объекты трех классов: parking, sequrityMan, polisMan
Подпишемся на события.
На событие NotPlaces подпишем объекты sequrityMan и polisMan
На событие SignalTriggered подпишем объект polisMan
Так как события статические, то применяем их не объекту, а к классу.
В цикле, пока у объекта parking значение логического поля= true (места есть), выполняем:
Лямбда выражения - это анонимные функции, с помощью которых можно очень сильно упростить текст кода. Например, с использованием лямбда выражений можно одной строкой кода найти сумму элементов коллекций, найти максимум или минимум, а также сделать выборку из массива и даже передать полученные результаты в метод.Лямбда выражения для коллекций являются по сути аналогом SQL запросов к базам данных.
Из коллекции класса Employee выбираются и выводятся на экран участники проекта старше 16 лет., но моложе 46 лет.
В коллекции класса Employee находим и выводятся на экран самого старшего участника.