JS ++ | Обработчики событий
Мы сделали наш класс Animal абстрактным. Мы объявили абстрактный метод разговора и реализовали этот метод во всех подклассах Animal. Однако наши животные пока не разговаривают. Нам нужен способ заставить животных что-то делать, когда происходит какое-то событие. В этом случае мы хотим «сделать что-нибудь», чтобы животное заговорило, а «событие», которое должно произойти, будет щелчком мыши пользователя. Мы можем сделать это с помощью обработчиков событий.
jQuery обеспечивает обработку событий, но мы собираемся определить обработчики событий объектно-ориентированным способом. С абстрактными классами вам не нужно привязывать события к каждому отдельному классу. Вместо этого вы можете прикрепить событие к абстрактному классу и применить его ко всем подклассам.
Измените Animal.jspp следующим образом:
внешний $; модуль Животные { абстрактный класс Animal { защищенный элемент var $; частный статический беззнаковый int count = 0; protected Animal (string iconClassName) { строковый элементHTML = makeElementHTML (iconClassName); $ element = $ (elementHTML); attachEvents (); Animal.count ++; } public static unsigned int getCount () { return Animal.count; } public virtual void render () { $ ("# содержание"). append ($ element); } public abstract void talk (); private void attachEvents () { $ element.click (разговор); } частная строка makeElementHTML (строка iconClassName) { строка result = '<div class = "animal">'; результат + = '<i class = "icofont' + iconClassName + '"> </i>'; результат + = "</div>"; вернуть результат; } } }
Это все, что вам нужно добавить. Скомпилируйте проект и попробуйте нажимать на животных. Вы должны увидеть окна сообщений, которые появляются, когда вы нажимаете на животное (кроме носорога), и видите шум, который оно издает:
Разберем код. Мы объявили частный метод attachEvents. Мы сделали его закрытым, потому что он нужен только классу Animal. В конструкторе Animal мы вызываем метод attachEvents. На этом этапе это должно быть просто. Вот код с новым материалом; внутри метода attachEvents у нас есть такой оператор:
$ element.click (разговор);
Как вы помните, через наследование каждый подкласс Animal также будет иметь в качестве данных элемент $ element. Этот элемент уникален для каждого экземпляра класса. Поле «$ element» представляет объект jQuery, обозначенный его префиксом $. Затем мы используем jQuery для присоединения «прослушивателя событий» к этому элементу $ element, уникальному для каждого экземпляра.
Таким образом, когда мы создаем экземпляры «Cat», «Dog», «Panda» и «Rhino», мы будем выполнять соответствующие конструкторы для каждого, которые начинаются с выполнения вызова super () для наследования от класса «Animal». «Animal», в свою очередь, создает уникальный «$ element» для экземпляра класса и присоединяет к элементу прослушиватель событий «click». Таким образом, к каждому из наших экземпляров было прикреплено событие, хотя был изменен только абстрактный базовый класс («Животное»).
Кроме того, мы передали метод talk как ссылку на click. И «щелчок», и «разговор» являются функциями. Однако только «щелчок» использует синтаксис вызова функции (в круглых скобках). Мы не добавляли скобки после слова «разговор». Причина в том, что мы не хотим, чтобы «разговор» немедленно выполнялся. Мы хотим, чтобы «разговор» выполнялся только тогда, когда происходит событие «щелчок».
Слушатель событий будет ждать, пока не произойдет событие. В этом случае мы прикрепили событие click, чтобы событие запускалось, когда пользователь щелкает элемент мышью. Наконец, мы должны указать, какой метод будет выполняться при щелчке по элементу:
$ element.click ( разговор );
Как видите, мы передали метод talk в качестве «обработчика событий». Обработчик событий - это метод, который запускается при срабатывании события. Другими словами, мы хотим, чтобы метод talk выполнялся при щелчке по элементу.
Однако «разговор» абстрактен. JS ++ распознает, что у нас есть абстрактный класс, и мы передаем абстрактный метод. Поскольку абстрактные методы не могут быть выполнены, JS ++ разрешит выполнение правильного метода. В этом случае он будет разрешен в реализации соответствующего подкласса talk.