通过其他接口实现在Java中实例化匿名内部类



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

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

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

让我们转到JLS:

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

class实例创建表达式为

ClassInstanceCreationExpression:
    new TypeArgumentsopt TypeDeclSpecifier TypeArgumentsOrDiamondopt
                                                            ( ArgumentListopt ) ClassBodyopt
    Primary . new TypeArgumentsopt Identifier TypeArgumentsOrDiamondopt
                                                            ( ArgumentListopt ) ClassBodyopt
TypeArgumentsOrDiamond:
    TypeArguments
    <> 
ArgumentList:
    Expression
    ArgumentList , Expression

所以,不,Java语言规范不允许任何捷径使您的匿名类实现更多的接口。

so,确定匿名类的类型

如果类实例创建表达式在班级主体中结束,则 正在实例化的课程是匿名类。然后:

  • 如果t表示接口,则是对象的匿名直接子类 该实现t命名的接口被声明。

[...]

  • 让t为标识符和任何类型参数的类型。一个 宣布了由T命名的类的匿名直接子类。这 子类的主体是类实例中给出的类 创建表达。

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

您也可以使用本地类。

匿名类

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

最新更新