2011-08-17 28 views
7

Tôi có một lớp Java trừu tượng cần phải có một phương thức onMessage để được triển khai. Tôi biết rằng việc đóng cửa có thể dễ dàng thực hiện một giao diện Java bằng cách sử dụng từ khóa as, nhưng làm thế nào nó có thể mở rộng một lớp Java trừu tượng?Có thể một kết thúc Groovy mở rộng một lớp trừu tượng

Nếu nó không thể mở rộng, thì công việc nào tốt nhất có thể trong các trường hợp như vậy trong Groovy?

Đây là cách sử dụng của tôi trong Java, tôi đang tìm một cái gì đó tương tự có thể được thực hiện trong Groovy.

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

Trường hợp gọi lại thư là lớp trừu tượng của tôi mà tôi muốn sử dụng theo cách tương tự trong Groovy.

Trả lời

7

Tôi tin rằng bạn sẽ có thể làm:

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

Điều đó không làm việc?

Sửa

Để thực hiện cuộc gọi từ Bản đồ phương pháp trở lại lớp trừu tượng, cách duy nhất tôi có thể tìm thấy để làm điều đó là:

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

Điều đó sẽ hiệu quả. Trong thực tế, nếu MessageCallback chỉ có một phương thức, bạn có thể thực hiện điều này: def callback = {message -> doSomething()} như MessageCallback –

+0

@tim_yates Nó hoạt động một phần, lớp messagecallback có phương thức "done" khi tôi gọi bên trong đóng cửa, tôi đã nhận được ngoại lệ phương pháp còn thiếu. Trong java tôi chỉ cần sử dụng done(), tôi có nên sử dụng một số cú pháp khác trong Groovy không? – Abe

+1

Ahhh, nếu bạn cần gọi lại lớp Proxied, mọi thứ trở nên phức tạp ... Tôi sẽ xem xét xem liệu tôi có thể tìm ra thứ gì tốt hơn là viết một lớp cụ thể với các phương thức trống không, và sau đó ghi đè lên những thứ này trong ' metaClass' (là giải pháp duy nhất khác mà tôi có thể nghĩ đến) –

2

Yo có thể làm điều này:

Thực hiện phương thức trong bất kỳ lớp nào:

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

Trong lớp học chính trong phương pháp chính:

def outerMessage 

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

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

đầu ra của bạn sẽ hiển thị này:

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

Căn cứ vào @tim_yates, đây là một phiên bản của phương pháp mà tạo ra đối tượng của một lớp trừu tượng từ một đóng cửa. Tôi cần một cái gì đó như thế để có thể khởi tạo vật thể như vậy chỉ trong một dòng.

// 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') 
Các vấn đề liên quan