2011-11-17 3 views
32

У меня есть два интерфейса:Реализовать два интерфейса в анонимном классе

interface A { 
    void foo(); 
} 

interface B { 
    void bar(); 
} 

Я могу создавать анонимные экземпляры классов, реализующие либо из этих интерфейсов, как так:

new A() { 
    void foo() {} 
} 

или:

new B() { 
    void bar() {} 
} 

Я хочу создать анонимный класс, который реализует оба интерфейса. Нечто подобное (фиктивная):

new A implements B { 
    void foo() {} 
    void bar() {} 
} 

Это, очевидно, дает ошибку компиляции: «B не может быть разрешен к типу».

Обходной довольно прост:

class Aggregate implements A, B { 
    void foo() {} 
    void bar() {} 
} 

Затем я использую Aggregate, где я когда-либо использовал бы анонимный класс.

Мне было интересно, является ли законным анонимный класс для реализации двух интерфейсов.

+0

См. [Why-an-anonymous-class-cant-implement-multiple-interfaces-direct] (http://stackoverflow.com/questions/4774168/why-an-anonymous-class-cant-implement-multiple- interface-direct) – nawfal

ответ

52

«анонимный внутренний класс может продлить один подкласс или реализовать один интерфейс. В отличие от неанонимных классов (внутренние или иным образом), анонимный внутренний класс не может сделать оба. Другими словами, он не может одновременно расширить класс и реализовать интерфейс, и не может реализовать более одного интерфейса. "(http://scjp.wikidot.com/nested-classes)

7

для сохранения некоторых клавиш (например, если интерфейсы имеют много методов), вы можете использовать

abstract class Aggregate implements A,B{ 
} 

new MyObject extends Aggregate{ 
    void foo(){} 
    void bar(){} 
} 

Уведомление о ключ должен объявить Агрегат как абстрактный

+12

Другой альтернативой является создание агрегирования самого интерфейса: 'interface Aggregate extends A, B {}'. –

+7

на каком языке это скомпилируется? – nachokk

+2

В Java, например? –

13

Если вы решили сделать это, вы могли бы объявить третий интерфейс, C:

public interface C extends A, B { 
} 

Таким образом, вы можете объявить один анонимный внутренний класс, который является реализацией C.

полный пример может выглядеть следующим образом:

public class MyClass { 

    public interface A { 
    void foo(); 
    } 

    public interface B { 
    void bar(); 
    } 

    public interface C extends A, B { 
    void baz(); 
    } 

    public void doIt(C c) { 
    c.foo(); 
    c.bar(); 
    c.baz(); 
    } 

    public static void main(String[] args) { 
    MyClass mc = new MyClass(); 

    mc.doIt(new C() { 
     @Override 
     public void foo() { 
     System.out.println("foo()"); 
     } 

     @Override 
     public void bar() { 
     System.out.println("bar()"); 
     } 

     @Override 
     public void baz() { 
     System.out.println("baz()"); 
     } 
    }); 
    } 

} 

выход этого примера:

foo() 
bar() 
baz() 
0

Обратите внимание, что вы можете сделать с именем местных класса, которые реализуют два интерфейса:

void method() { 
    class Aggregate implements A, B { 
     void foo() {} 
     void bar() {} 
    } 

    A a = new Aggregate(); 
    B b = new Aggregate(); 
} 

Это избавит вас от этого класса уровня или объявление класса верхнего уровня.

Результат называется local class. Локальные классы, объявленные в методах экземпляра, также являются внутренними классами, что означает, что они могут ссылаться на экземпляр содержащегося объекта.

Смежные вопросы