使用Java中的接口的匿名内部类
因此,当查看lambda表达式并使用它们来替换Java中的EventHandlers的匿名内部类时,我遇到了一些让我停下来思考的匿名内部类。 例如,在为通常实现ActionListener的东西编写匿名内部类时,我们编写
myJButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e){ //DO SOMETHING } });
我对此感到困惑的是,ActionListener是一个界面,所以我认为有必要做一些像…
myJButton.addActionListener(new myButtonListener implements ActionListener() { @Override public void actionPerformed(ActionEvent e){ //DO SOMETHING } });
但这甚至都没有编译。 我想我之所以这是显而易见的,相反我们使用私有内部类,我们使用
private MyButtonListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { //DO SOMETHING } } myJButton.addActionListener(new MyButtonListener());
所以我的问题是:
1)为什么我们能够直接从接口创建匿名内部类而不必通过实现接口的类创建一个?
2)为什么我无法创建一个实现ActionListener的匿名内部类而不是直接来自它,就像我在第二个代码片段中显示的那样?
1)为什么我们能够直接从接口创建匿名内部类而不必通过实现接口的类创建一个?
2)为什么我无法创建一个实现ActionListener的匿名内部类而不是直接来自它,就像我在第二个代码片段中显示的那样?
当你使用implements
XXXX创建一个类时,你正在定义一个类(内部或非内部),你必须给它一个名字,确保我们可以做到这一点,这就是我们经常做的事情。 虽然匿名内部类没有名称,但它更像是一个表达式。
我从http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html复制了这个
我认为这将有助于您了解匿名类是什么。
匿名类是表达式。 它们就像本地类,除了它们没有名称
。 匿名类表达式的语法类似于构造函数的调用,除了代码块中包含类定义。
考虑frenchGreeting对象的实例化:
HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde"; public void greet() { greetSomeone("tout le monde"); } public void greetSomeone(String someone) { name = someone; System.out.println("Salut " + name); } };
匿名类表达式包含以下内容:
-
新的运营商
-
要实现的接口的名称或要扩展的类 。 在此示例中,匿名类正在实现接口HelloWorld。
-
包含构造函数参数的圆括号,就像普通的类实例创建表达式一样。 注意: 实现接口时,没有构造函数,因此您使用一对空括号 ,如本例所示。
-
身体,是一个类声明体。 更具体地说,在正文中,方法声明是允许的,但语句不是。
因为匿名类定义是表达式,所以它必须是语句的一部分。 在此示例中,匿名类表达式是实例化frenchGreeting对象的语句的一部分。 (这解释了为什么在闭合支撑后有一个分号。)