Frage

Let's say I have the following two class/interface definitions:

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

and

public interface BarInterface {
    public void doBar();
}

If I want to make an anonymous inner class that extends/implements both, do I need to do this:

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

Or is there a short-cut that allows me to not define BothClass? Something like this, maybe:

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

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

(This idea gives me several errors, none of which are helpful here)

War es hilfreich?

Lösung

Let's go to the JLS:

An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler.

where a class instance creation expression is

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

TypeArgumentsOrDiamond:
    TypeArguments
    <> 

ArgumentList:
    Expression
    ArgumentList , Expression

So, no, the Java language specification does not allow any shortcuts for making your anonymous class implement more interfaces than the type you're sub-typing.

So, to determine the type of the anonymous class

If the class instance creation expression ends in a class body, then the class being instantiated is an anonymous class. Then:

  • If T denotes an interface, then an anonymous direct subclass of Object that implements the interface named by T is declared.

[...]

  • Let T be the type named by the Identifier and any type arguments. An anonymous direct subclass of the class named by T is declared. The body of the subclass is the ClassBody given in the class instance creation expression.

Your alternative is the way to do it.

You can also use local classes.

Andere Tipps

An anonymous class

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

is just a convenient shorthand for a local class definition with a generated name

class $anon extends FooClass {
  public void doFoo() {}
}
FooClass f = new $anon();

If you want to implement interfaces just write the local class definition explicitly

class LocalFoo extends FooClass implements BarInterface {
  // method declarations here
}
LocalFoo lf = new LocalFoo();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top