第3行在ActionListener()
关键字后new
是什么意思?我知道这是匿名类的结构,但我没有得到它。
Button okButton = new Button("Open a Frame");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
statusLabel.setText("A Frame shown to the user.");
frame.setVisible(true);
}
});
答案 0 :(得分:2)
您正在创建匿名ActionListener
类并实施actionPerformed
方法。
答案 1 :(得分:2)
new ActionListener()
创建了ActionListener
类型的匿名内部类。由于ActionListener可能不是一个类,而是一个接口,因此您不能简单地创建一个新的实例,如Object obj = new Object();
并完成。您必须实现由该接口定义的方法。
在您的情况下,它只有一种方法actionPerformed
。
编辑:
我们假设ActionListener
是一个接口(public interface ActionListener
)而不是一个对象(public class ActionListener
),因为这是UI开发中最常见的事情。
如果您有以下代码:
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
statusLabel.setText("A Frame shown to the user.");
frame.setVisible(true);
}
});
你已经结合了很多语句,这会导致年轻和没有经验的开发人员进行某种混淆。 让我们稍微分开一下这些陈述,然后再对它进行反渗透
ActionListener myListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
statusLabel.setText("A Frame shown to the user.");
frame.setVisible(true);
}
});
okButton.addActionListener(myListener);
现在我们在第一行看到一个简单的对象实例,正如我们已经从其他对象知道的那样。但是,为什么我们需要开口括号,为什么我们需要实现一种方法?
这是因为我们假设ActionListener是一个接口。界面中定义的所有方法都是抽象的,需要先实现,然后才能以任何方式使用。 (一方面认为,如果ActionListener是class
,方法actionPerformed
将在类中定义为abstract
所以你基本上实现了一个界面。但等等,因为什么时候可以实现接口? 因为你用它作为匿名!
可以将实例编写为抽象代码:
ActionListener myListener = new Object implements ActionListener;
Object implements ActionListener
的构造确实导致了一种没有名字的新类型,这就是匿名的原因。由于它没有名称,因此无法在其他地方创建其他实例。
如果你将整个代码分开并且"提取"匿名部分不再是匿名的,你最终会得到这样的东西:
//Class MyListener
public class MyListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
statusLabel.setText("A Frame shown to the user.");
frame.setVisible(true);
}
}
//Class FooBar
MyListener myListener = new MyListener();
okButton.addActionListener(myListener);
答案 2 :(得分:1)
此语法:
new ActionListener() { ... }
定义了一个实现ActionListener接口的匿名类。您没有创建ActionListener的实例;您正在创建此匿名类的实例。 (编译器实际上为它指定了一个名称 - 通常类似于MyEnclosingClass$1
。这个匿名类将有一个单独的.class
文件。)您可以在Java教程中阅读有关匿名内部类的更多信息。
您可以在函数调用中立即使用此新对象(与第一个代码段一样),也可以将其分配给具有与ActionListener分配兼容的类型的变量。
ActionListener al = new ActionListener() { ... };