¿Cómo puede una clase anónima usar "extiende" o "implementa"?

96

¿Cómo puede una clase anónima extender una superclase o implementar una interfaz?

Mike Rylander
fuente
Desafortunadamente, debe hacer que el constructor sea visible en lugares que de otro modo no lo sería.
Sridhar Sarnobat

Respuestas:

98

Las clases anónimas deben extender o implementar algo, como cualquier otra clase de Java, incluso si es solo java.lang.Object.

Por ejemplo:

Runnable r = new Runnable() {
   public void run() { ... }
};

Aquí, rhay un objeto de una clase anónima que implementa Runnable.

Una clase anónima puede extender otra clase usando la misma sintaxis:

SomeClass x = new SomeClass() {
   ...
};

Lo que no puede hacer es implementar más de una interfaz. Necesita una clase con nombre para hacer eso. Sin embargo, ni una clase interna anónima ni una clase con nombre pueden extender más de una clase.

skaffman
fuente
1
No creo que la segunda expresión sea correcta. Ya ha declarado el nombre de la clase como SomeClass, ya no es anónimo. Consulte este enlace docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm Cuando "nueva" una interfaz, se crea una clase anónima al extender la clase "Objeto" e implementar esa interfaz. Pero mientras está "renovando" una clase con la primera expresión que escribió, se creará una clase anónima (de hecho, es una instancia de esa clase anónima creada) al extender esa clase.
lixiang
8
@youmiss: La segunda expresión creará una instancia de una clase anónima que se extiende SomeClass. Todavía es anónimo, debido al {...}.
skaffman
1
Ya veo, pasé por alto el {...}.
lixiang
36

Una clase anónima generalmente implementa una interfaz:

new Runnable() { // implements Runnable!
   public void run() {}
}

JFrame.addWindowListener( new WindowAdapter() { // extends  class
} );

Si te refieres a si puedes implementar 2 o más interfaces, creo que eso no es posible. A continuación, puede crear una interfaz privada que combine los dos. Aunque no puedo imaginar fácilmente por qué querrías que una clase anónima tuviera eso:

 public class MyClass {
   private interface MyInterface extends Runnable, WindowListener { 
   }

   Runnable r = new MyInterface() {
    // your anonymous class which implements 2 interaces
   }

 }
extraneón
fuente
Me gusta esta respuesta porque es compatible con Google para las personas que buscan implementar 2 o más interfaces en una implementación anónima.
L. Holanda
16

Las clases anónimas siempre extienden la superclase o implementan interfaces. por ejemplo:

button.addActionListener(new ActionListener(){ // ActionListener is an interface
    public void actionPerformed(ActionEvent e){
    }
});

Además, aunque la clase anónima no puede implementar múltiples interfaces, puede crear una interfaz que amplíe otra interfaz y dejar que su clase anónima la implemente.

MByD
fuente
11

Supongo que nadie entendió la pregunta. Supongo que lo que quería este tipo era algo como esto:

return new (class implements MyInterface {
    @Override
    public void myInterfaceMethod() { /*do something*/ }
});

porque esto permitiría cosas como múltiples implementaciones de interfaz:

return new (class implements MyInterface, AnotherInterface {
    @Override
    public void myInterfaceMethod() { /*do something*/ }

    @Override
    public void anotherInterfaceMethod() { /*do something*/ }
});

esto sería realmente bueno; pero eso no está permitido en Java .

Lo que puede hacer es usar clases locales dentro de bloques de métodos:

public AnotherInterface createAnotherInterface() {
    class LocalClass implements MyInterface, AnotherInterface {
        @Override
        public void myInterfaceMethod() { /*do something*/ }

        @Override
        public void anotherInterfaceMethod() { /*do something*/ }
    }
    return new LocalClass();
}
Thiagoh
fuente
Exactamente, esto es lo que pretendía el OP en mi humilde opinión
DanielCuadra
dando un pulgar por responder la pregunta formulada. lo cual es normal en SO que a la gente le gusta responder lo que se debe preguntar, no lo que se ha preguntado.
mfaisalhyder
3
// The interface
interface Blah {
    void something();
}

...

// Something that expects an object implementing that interface
void chewOnIt(Blah b) {
    b.something();
}

...

// Let's provide an object of an anonymous class
chewOnIt(
    new Blah() {
        @Override
        void something() { System.out.println("Anonymous something!"); }
    }
);
Oliver Charlesworth
fuente
1

Una clase anónima se está ampliando o implementando mientras crea su objeto. Por ejemplo:

Interface in = new InterFace()
{

..............

}

Aquí la clase anónima está implementando Interface.

Class cl = new Class(){

.................

}

aquí la clase anónima está ampliando una clase abstracta.

trapedInBatcaveWithBAtman
fuente
No veo la diferencia. Cómo el tuyo es diferente al mío.
trapedInBatcaveWithBAtman
uno agradable y compacto, lo que extraño en tu respuesta es una palabra como "siempre" o "debe" :)
kiedysktos