JS++ 事件处理程序
我们已经使我们的’动物’类成为抽象的。我们声明了一个抽象的 “说话 “方法,并在 “动物 “的所有子类中实现了这个方法。然而,我们的动物还不会说话。我们需要一种方法来使动物在事件发生时做一些事情。在这种情况下,我们想要的 “做事 “是让动物说话,而需要发生的 “事件 “将是用户的鼠标点击。我们可以用事件处理程序来完成这个任务。
jQuery提供了事件处理功能,但我们要以面向对象的方式来定义事件处理程序。有了抽象类,你不需要把事件挂在每个单独的类上。相反,你可以将一个事件附加到抽象类,并让它应用于所有的子类。
修改Animal.jspp如下。
external ;
module Animals
{
abstract class Animal
{
protected varelement;
private static unsigned int count = 0;
protected Animal(string iconClassName) {
string elementHTML = makeElementHTML(iconClassName);
element =(elementHTML);
attachEvents();
Animal.count++;
}
public static unsigned int getCount() {
return Animal.count;
}
public virtual void render() {
("#content").append(element);
}
public abstract void talk();
private void attachEvents() {
$element.click(talk);
}
private string makeElementHTML(string iconClassName) {
string result = '<div class="animal">';
result += '<i class="icofont ' + iconClassName + '"></i>';
result += "</div>";
return result;
}
}
}
这就是你所要添加的全部内容。编译该项目并尝试点击动物。你应该看到当你点击一个动物(除了犀牛)时弹出的信息框,并看到它发出的声音。
让我们来分解一下代码。我们声明了一个私有的’attachEvents’方法。我们让它成为’私有’,因为只有’动物’类需要它。在 “动物 “构造函数中,我们调用 “attachEvents “方法。在这一点上,这应该是很直接的。这里是带有新材料的代码;在’attachEvents’方法中,我们有这样的语句。
$element.click(talk);
你会记得,通过继承,’动物’的每个子类也会有’element’作为数据。这个元素对每个类的实例都是唯一的。element “字段代表一个jQuery对象,由前缀表示。然后我们用jQuery给这个’element’附加一个’事件监听器’,这个监听器对每个实例都是唯一的。
因此,当我们实例化 “猫”,”狗”,”熊猫 “和 “犀牛 “时,我们将执行各自的构造函数,开始执行super()调用以继承 “动物 “类。动物 “反过来为该类实例创建一个独特的”$element”,并将 “点击 “事件监听器附加到该元素。因此,我们的每一个实例都有一个事件附加到它上面,尽管只有抽象的基类(’Animal’)被修改。
另外,我们把’talk’方法作为’click’的一个引用来传递。’click’和’talk’都是函数。然而,只有’click’使用了函数调用语法(带括号)。我们没有在’talk’后面添加括号。原因是我们不希望’talk’立即执行。我们只想让’talk’在’click’事件发生时执行。
一个事件监听器将等待事件发生。在这种情况下,我们附加了一个’点击’事件,所以当用户用鼠标点击该元素时,该事件将被触发。最后,我们必须指定当元素被点击时哪个方法被执行。
$element.click(talk);
正如你所看到的,我们传递了’talk’方法作为 “事件处理程序”。事件处理程序是当事件被触发时被执行的方法。换句话说,我们希望’talk’方法在元素被点击的时候执行。
然而,’talk’是抽象的。JS++认识到我们有一个抽象的类,我们正在传递一个抽象的方法。由于抽象方法不能被执行,JS++将解析正确的方法来执行。在这种情况下,它将解析到’talk’的各个子类实现。