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

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クラス風に書いた場合

これをInnerクラスで書きたいところだが、Groovyでは書けない。 そこで Closure と as を使って、 Innerクラスっぽく書くと...

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

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

// test1
def c1 = { name -> println 'Hello '+name }
def c1Hello = c1 as Hello
c1Hello.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)

ポイント

button.addActionListener( {e->
    println 'test button clicked '+ e.getClass().name
} as ActionListener )
 Twitter
follow me on Twitter
 Categories