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。它通常用于侦听器(如ActionListener
s),但仅应在您不必删除侦听器时使用,因为没有保存引用。
对于问题的第二部分,编译器不知道何时调用actionPerformed
. 它在ActionListener
文档中声明:
当动作事件发生时,该对象的 actionPerformed 方法被调用。
因此,每当动作发生时,调用已添加到它的所有s 是JButton
s 的责任。actionPerformed
ActionListener
没有办法提出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 classes
ActionListener
该addActionListener
方法知道它有一个actionPerformed
方法(它必须有一个),所以它会自动调用它