3 回答
您给出的第一个示例称为“匿名内部类”。您正在定义 的匿名子类ActionListener,覆盖其actionPerformed方法,实例化它(创建此子类的实例),然后将对该实例的引用传递给方法jbnButton1.addActionListener。这是目前最接近 Java 的“闭包”(至少在 Java 8 之前)。
当动作侦听器很简单时,这是惯用的,但您可以将其重新编码为
class MyListener extends ActionListener
{
public void actionPerformed(ActionEvent e)
{
jtfInput.setText("Button 1!");
}
}
...
jbnButton1.addActionListener(new MyListener());
但是您可能必须安排一个构造函数MyListener来接受并保存jtfInput引用。内联定义简化了这一点。但是对于更复杂的情况,您可能希望离线定义类。
至于第二个问题:
.addActionListener(this);
这个出现的类必须实现ActionListener接口,所以它必须有一个actionPerformed()方法。这就是让框架“知道”要调用什么的原因。
您的第一个示例称为Anonymous Class。它通常用于侦听器(如ActionListeners),但仅应在您不必删除侦听器时使用,因为没有保存引用。
对于问题的第二部分,编译器不知道何时调用actionPerformed. 它在ActionListener 文档中声明:
当动作事件发生时,该对象的 actionPerformed 方法被调用。
因此,每当动作发生时,调用已添加到它的所有s 是JButtons 的责任。actionPerformedActionListener
没有办法提出b1和b3指出不同的方法。这是一个很好的例子,说明匿名类可以带来更好的设计:
b1.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
b2.setEnabled(false);
b1.setEnabled(false);
b3.setEnabled(true);
}
});
b3.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
b2.setEnabled(true);
b1.setEnabled(true);
b3.setEnabled(false);
}
});
假设b1有标签“禁用”。那么this就不用再执行了ActionListener。
对于您的第二个代码示例:
它知道要使用它,actionperformed()因为您用来将actionlistener-s 添加到按钮的类正在实现接口ActionListener
如果你将addActionListener你自己的类(this)传递给你必须实现方法的方法,它actionPerformed就像anonymous classesActionListener
该addActionListener方法知道它有一个actionPerformed方法(它必须有一个),所以它会自动调用它