Home About
Groovy

as を使って Innerクラスの代わりに Closure を使って Innerクラスっぽく記述する方法, Groovy

Grails徹底入門を読んでいたら Innerクラスの代わりに AS を使うという説明が載っていた。
たとえば、RunnableインタフェースをClosureを使って記述するには...

def c = {
    println 'Hello'
}

def c2 = c as Runnable
new Thread(c2).start()

というような例が出ていたような気がする。

自分で定義したインタフェースでも機能するかのテスト

Java風にそのまま書いた場合

interface Hello{
    void say()
}
class HelloImpl implements Hello{
    void say(){ println 'Hello' }
}

new HelloImpl().say()

closureとasを使って Innerクラス風に書いた場合

これを Closure と as を使って、Innerクラスっぽく書くと…

interface Hello{
    void say()
    void say(String name)
}

// test0
def c0 = { println 'Hello' } as Hello
c0.say()

// test1
def c1 = { name -> println 'Hello '+name } as Hello
c1.say('Taro')

引数の数で自動的に呼ぶべきメソッドが選択されているようだ。

AWT や Swing でありがちなActionListenerを Closure + as で記述する

ボタンがクリックされたかを検出するために、ActionListenerを使うわけだが、それを Closureで書いた groovy コード。

import java.awt.*
import java.awt.event.*
import javax.swing.*

class MyFrame extends JFrame{

    def MyFrame(){
        def button = new JButton('test')
        button.addActionListener( {e->
            println 'test button clicked '+ e.getClass().name
        } as ActionListener )

        add( button,BorderLayout.NORTH )
    }
}

frame = new MyFrame()
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)
frame.setSize(400,300)
frame.setVisible(true)

addActionListener の部分がシンプルに書けるのがうれしいですね。