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.