2011-08-17 8 views
7

Uygulanacak bir yöntem onMessage olması gereken soyut bir Java sınıfım var. Bir kapanışın, as anahtar sözcüğünü kullanarak bir Java arayüzünü kolayca uygulayabildiğini biliyorum, ancak soyut bir Java sınıfını nasıl genişletebilirim?Bir Groovy kapatma, bir soyut sınıf genişletebilir

Genişletemezse, bu durumda Groovy'deki olası en iyi çalışma nedir?

İşte Java'daki kullanımım, Groovy'de yapılabilecek benzer bir şey arıyorum.

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

mesajı geri arama ben Groovy benzer bir şekilde kullanmak istiyorum benim soyut sınıftır

.

cevap

7

Ne yapmaya muktedir gerektiğine inanıyoruz:

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

çalışmıyor mu?

Düzenleme

geri Özet sınıfa Harita yönteminden arama yapmak için tek yol bunu yapmak için bulabilirsiniz geçerli:

// 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

Çalışması gerekir. Aslında, MessageCallback'in yalnızca bir yöntemi varsa, bunu yalnızca yapabilirsiniz: def callback = {message -> doSomething()} MessageCallback olarak –

+0

@tim_yates Kısmen çalıştı, messagecallback sınıfının içinde çalıştığım bir "done" yöntemi vardı. Kapatma, eksik yöntem istisnası var. Java'da sadece kullanıyorum(), Groovy'de başka bir sözdizimini kullanmalı mıyım? – Abe

+1

Ahhh, eğer Proxied sınıfına geri dönmeniz gerekiyorsa, işler zorlaşıyor ... Boş bir yöntemle somut bir sınıf yazmaktan daha iyi bir şeyle gelip gelemeyeceğimi görüp, sonra bunları üzerine yazacağım. metaClass' (şu anda düşünebildiğim tek diğer çözüm) –

2
Yo yapabilirsiniz

:

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

herhangi bir sınıfta bir yöntemi uygular Ana yönteminde ana sınıfta

:

bu göstermelidir Çıktınız

def outerMessage 

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

messageTest.onMessage("This is the message...") 
println "outerMessage: $outerMessage" 
: @tim_yates üzerine

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

oturtmakta, burada gelen soyut bir sınıf nesnesi oluşturur yöntemin bir versiyonudur kapatma. Böyle bir nesneyi sadece bir satırda oluşturabilmek için böyle bir şeye ihtiyacım vardı.

// 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')