2011-08-17 3 views
7

У меня есть абстрактный класс Java, который должен иметь один метод onMessage, который будет реализован. Я знаю, что закрытие может легко реализовать интерфейс Java, используя ключевое слово as, но как он может расширить абстрактный класс Java?Может ли расширение Groovy расширить абстрактный класс

Если он не может его продлить, то какова самая лучшая работа в таких случаях в Groovy?

Вот мое использование в Java, я ищу что-то подобное, что можно сделать в Groovy.

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

Где сообщение обратного вызова мой абстрактный класс, который я хотел бы использовать аналогичным образом в Groovy.

ответ

7

Я считаю, что вы должны быть в состоянии сделать:

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

ли это, что не работает?

Редактировать

Чтобы сделать вызов из метода Карта назад в абстрактный класс, единственный способ, которым я могу найти, чтобы сделать это:

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

Это должно сработать. Фактически, если MessageCallback имеет только один метод, вы можете просто сделать это: def callback = {message -> doSomething()} как MessageCallback –

+0

@tim_yates Он работал частично, класс messagecallback имел метод «done», который, когда я вызывал внутри закрытие, я получил исключение исключающего метода. В java я просто использую done(), следует ли использовать другой синтаксис в Groovy? – Abe

+1

Ahhh, если вам нужно перезвонить в класс Proxied, все будет сложно ... Я посмотрю и посмотрю, смогу ли я придумать что-нибудь лучше, чем написать конкретный класс с пустыми методами, а затем переписать их в ' metaClass' (который является единственным другим решением, о котором я могу сейчас думать) –

2

Yo можно сделать так:

Реализует метод в любом классе:

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

В главном классе в основной метод:

def outerMessage 

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

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

Ваш выход должен показать это:

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

Базирование на @tim_yates, вот вариант метода, который создает объект абстрактного класса из закрытие. Мне нужно было что-то подобное, чтобы создать экземпляр такого объекта только в одной строке.

// 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') 
Смежные вопросы