Java初始化抽象类

4

可以有人为我解释一下这行代码吗?

SomeAbstractClass variable = new SomeAbstractClass() { };

这会正确地实例化并将抽象实例存储在变量中。发生了什么?可能是扩展抽象类的匿名类?有任何关键字可以用来查找此类信息吗?(如果抽象类也是通用的,那么是否具有任何相关性)

(这是使用Java编写的代码。上面的行创建了一个匿名内部类,该类继承自SomeAbstractClass,并在花括号内定义新行为。这是Java中的一种非常有用的技术,称为匿名内部类。)

1
你问题中的关键词是anonymous和extends。 - Sotirios Delimanolis
3个回答

8
上面这行代码创建了一个匿名子类类,该类不会是abstract抽象的。当然,这只有在基类没有需要实现的抽象方法时才会起作用。
除了“文档”功能(请参见下面的注释),我实际上无法想象出上面那行代码的有用实例,除非您正在实现和/或覆盖花括号之间的方法。如果基类/接口恰好有少量要实现且实现很简单的方法,则这是一种常见的技术。您甚至可以引用周围方法的final变量和参数,从而创建闭包。

1
我在单元测试的模拟对象中看到过这种情况,真正的应用程序应该始终使用派生类。在这种情况下,“抽象”更多地是一个文档特性和一个警告,以避免创建基类的实例,而不是必要的实现。 - kiheru
@kiheru 不错。我已经在回答中加入了指向您评论的指针。 - Stefano Sanfilippo
要引用周围方法中的变量,它们也需要是“final”。即使它们是,匿名内部类也只是有效地创建了一个闭包。它并不是真正的闭包。 - Vidya

1
您正在创建一个匿名类,它是抽象类的子类。正如评论中指出的那样,您正在查看匿名扩展。如果您有要实现的抽象方法,则可以使用以下内容:
MyAbstractClass someObjectOfThatClass = new MyAbstractClass(){
                       @Override
                       public void someAbstractMethod(){

                       }
                    }  

你可以使用接口做同样的事情,因为它们也可以包含抽象方法。一个实际的例子是将 ActionListener 添加到 JButton 中:
myJButton.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e){
                    // code
                }
            });

1
@StefanoSanfilippo 我认为一点幽默会有帮助。 - An SO User

1
Java使您能够内联创建匿名子类。通常在Swing事件处理的匿名内部类上看到这一点,但还有许多其他应用程序。
在您的示例中,您正在创建一个匿名扩展SomeAbstractClass的类,并将其分配给SomeAbstractClass引用。这就像您创建了一个单独的类一样。
public class SomeConcreteClass extends SomeAbstractClass {
}

然后做了这个

SomeAbstractClass variable = new SomeConcreteClass();

正如@Stefano所指出的那样,您的方法仅在您的匿名具体类没有抽象方法时才有效,这是正确的,因为SomeAbstractClass没有抽象方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接