2011-08-17 23 views
7

Tengo una clase abstracta de Java que necesita tener un método onMessage para implementarse. Sé que un cierre puede implementar fácilmente una interfaz Java usando la palabra clave as, pero ¿cómo puede extender una clase abstracta de Java?¿Puede un cierre Groovy extender una clase abstracta

Si no puede ampliarlo, ¿cuál es el mejor trabajo posible en estos casos en Groovy?

Aquí está mi uso en Java, estoy buscando algo similar que se pueda hacer en Groovy.

MessageCallback callback = new MessageCallback() { 
      @Override 
      public void onMessage(Message message) { 
       dosomething(); 
      } 
     }; 

donde el mensaje de devolución de llamada es mi clase abstracta que me gustaría utilizar de una manera similar en Groovy.

Respuesta

7

creo que debería ser capaz de hacer:

def callback = [ onMessage:{ message -> doSomething() } ] as MessageCallback 

¿Eso no funciona?

Edición

Para realizar una llamada desde el método Mapa de nuevo a la clase abstracta, la única manera que se puede encontrar para hacerlo es:

// Dummy class for testing 
abstract class MessageTest { 
    abstract void onMessage(msg) ; 
    void done() { println "DONE!" } 
} 

// Create a Proxied instance of our class, with an empty onMessage method 
def p = [ onMessage:{ msg -> } ] as MessageTest 

// Then overwrite the method once we have access to the Proxy object p 
p.metaClass.onMessage = { msg -> println msg ; p.done() } 

// Test 
p.onMessage('woo') 
+2

Eso debería funcionar. De hecho, si MessageCallback solo tiene un método, puede hacer esto: callback def = {message -> doSomething()} como MessageCallback –

+0

@tim_yates Funcionó parcialmente, la clase messagecallback tenía un método "hecho" que cuando invocaba dentro el cierre, recibí la excepción del método faltante. En Java solo uso done(), ¿debería usar alguna otra sintaxis en Groovy? – Abe

+1

Ahhh, si necesita volver a llamar a la clase Proxied las cosas se complican ... Voy a echar un vistazo y ver si puedo encontrar algo mejor que escribir una clase concreta con métodos vacíos y luego sobrescribirlos en ' metaClass' (que es la única otra solución en la que puedo pensar actualmente) –

2

Yo puede hacer esto:

implementa un método en cualquier clase:

public MessageTest messageTest(Closure callback) { 
    return new MessageTest() { 
     @Override 
     public void onMessage(Message message) { 
      callback.call(message) 
     } 
    } 
} 

En clase principal en el método principal:

def outerMessage 

MessageTest messageTest = messageTest() {message -> 
    outerMessage = message 
    println "innerMessage: $message" 
} 

messageTest.onMessage("This is the message...") 
println "outerMessage: $outerMessage" 

Su salida debería mostrar esto:

innerMessage: This is the message... 
outerMessage: This is the message... 
1

basándose en @tim_yates, aquí es una versión del método que crea objeto de una clase abstracta de una cierre. Necesitaba algo así para poder crear una instancia de dicho objeto en una sola línea.

// Dummy class for testing 
abstract class MessageTest { 
    abstract void onMessage(msg) ; 
    void done() { println "DONE!" } 
} 

MessageTest createMessageTest(Closure closure) { 
    // Create a Proxied instance of our class, with an empty onMessage method 
    def p = [ onMessage:{ msg -> } ] as MessageTest 

    // Then overwrite the method once we have access to the Proxy object p 
    p.metaClass.onMessage = closure 
    return p 
} 

// Create 
MessageTest mt = createMessageTest { msg -> 
    println msg ; 
    done() 
} 

// Test 
mt.onMessage('woo') 
Cuestiones relacionadas