使用额外的接口实现在Java中实例化匿名内部类

时间:2014-02-02 20:20:39

标签: java subclassing anonymous-inner-class interface-implementation

假设我有以下两个类/接口定义:

public abstract class FooClass {
    public abstract void doFoo();
}

public interface BarInterface {
    public void doBar();
}

如果我想创建一个扩展/实现两者的匿名内部类,我是否需要这样做:

public abstract class BothClass extends FooClass implements BarInterface {}

...

new BothClass() {
    public void doFoo() {
        System.out.println("Fooooooooo!!!!");
    }

    public void doBar() {
        System.out.println("Baaaaaaaar!!!!");
    }
}.doBar();

或者是否有一个允许我不定义BothClass的捷径?这样的事情,也许是:

new (FooClass implements BarInterface)() {
    public void doFoo() {
        System.out.println("Fooooooooo!!!!");
    }

    public void doBar() {
        System.out.println("Baaaaaaaar!!!!");
    }
}.doBar();

(这个想法给了我几个错误,这里没有任何错误)

2 个答案:

答案 0 :(得分:9)

Let's go to the JLS:

  

匿名类声明自动从类派生   Java编译器创建实例表达式。

其中类实例创建表达式为

ClassInstanceCreationExpression:
    new TypeArgumentsopt TypeDeclSpecifier TypeArgumentsOrDiamondopt
                                                            ( ArgumentListopt ) ClassBodyopt
    Primary . new TypeArgumentsopt Identifier TypeArgumentsOrDiamondopt
                                                            ( ArgumentListopt ) ClassBodyopt

TypeArgumentsOrDiamond:
    TypeArguments
    <> 

ArgumentList:
    Expression
    ArgumentList , Expression

所以,不,Java语言规范不允许任何快捷方式使您的匿名类实现比您要子类型的类型更多的接口。

所以,到determine the type of the anonymous class

  

如果类实例创建表达式在类主体中结束,那么   被实例化的类是一个匿名类。然后:

     
      
  • 如果T表示接口,则表示Object的匿名直接子类   实现了由T命名的接口的声明。
  •   
     

[...]

     
      
  • 设T是由Identifier和任何类型参数命名的类型。一个   声明了由T命名的类的匿名直接子类。该   子类的主体是类实例中给出的ClassBody   创作表达。
  •   

你的另类方法是做到这一点。

您也可以使用local classes.

答案 1 :(得分:0)

匿名类

FooClass f = new FooClass() {
  public void doFoo() {}
};

只是具有生成名称

的本地类定义的便捷简写
class $anon extends FooClass {
  public void doFoo() {}
}
FooClass f = new $anon();

如果要实现接口,只需显式编写本地类定义

class LocalFoo extends FooClass implements BarInterface {
  // method declarations here
}
LocalFoo lf = new LocalFoo();
相关问题