覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Kotlin - オブジェクト式

Kotlin の object キーワードは、無名オブジェクト(anonymous object)の宣言のためにも使用できます。
無名オブジェクト は Javaにおける無名内部クラスを置き換えるものとなります。

Javaで無名内部クラスの典型的な利用シーンというと、イベントリストが必要となるケースがあります。

例えば以下のようなJavaのコードがあったとした場合(import 等もろもろ省略)

JWindow window = new JWindow();
window.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("Mouse Clicked");
    }

    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println("Mouse Pressed");
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        System.out.println("Mouse Released");
    }
});

上記コードは Kotlin ではオブジェクト式で以下のように記述できます。

val window = JWindow()
window.addMouseListener(
    object : MouseAdapter() {
        override fun mouseClicked(e: MouseEvent) {
            println("Mouse Clicked")
        }

        override fun mousePressed(e: MouseEvent) {
            println("Mouse Pressed")
        }

        override fun mouseReleased(e: MouseEvent) {
            println("Mouse Released")
        }
    }
)

オブジェクトの名前を省略しているという点をを除いて、オブジェクト宣言と同じです。
オブジェクト式はクラスを宣言し、そのクラスのインスンスを生成しています。


Javaの無名クラスと同様にオブジェクト式の中のコードは、それが生成された関数内の変数を参照することができます。
しかし、Javaとは違って、その変数がfinalでなければならないという制約はありません。
そのため、オブジェクト式の中から変数の値を変更することも可能です。

以下のようなコードを書くことも可能です

var count = 0
val window = JWindow()
window.addMouseListener(
    object : MouseAdapter() {
        override fun mouseClicked(e: MouseEvent) {
            println("Mouse Clicked")
            count++
        }

        override fun mousePressed(e: MouseEvent) {
            println("Mouse Pressed")
            count++
        }

        override fun mouseReleased(e: MouseEvent) {
            println("Mouse Released")
            count++
        }
    }
)


まとめ

オブジェクト式により Java の無名内部クラスを置き換えることができることがわかりました。