4

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

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();

(这个想法给了我几个错误,这里没有一个有帮助)

4

2 回答 2

9

让我们去JLS:

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

类实例创建表达式在哪里

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

TypeArgumentsOrDiamond:
    TypeArguments
    <> 

ArgumentList:
    Expression
    ArgumentList , Expression

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

所以,要确定匿名类的类型

如果类实例创建表达式以类体结尾,则被实例化的类是匿名类。然后:

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

[...]

  • 令 T 为由 Identifier 和任何类型参数命名的类型。声明了由 T 命名的类的匿名直接子类。子类的主体是类实例创建表达式中给出的 ClassBody。

您的选择是这样做的方法。

您也可以使用本地类。

于 2014-02-02T20:26:27.067 回答
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();
于 2014-02-02T21:38:36.210 回答