カテゴリー
Kotlin言語

インタフェースとラムダ式(Kotlin編)

アプリのボタンがタップされたときの処理をまじめに書くと、かなりごちゃごちゃしてしまいます。ラムダ式を使うとこの処理を簡単に記述することができます


ボタンがタップされたときの処理

ボタンがタップされたとき処理を詳しくみておきますね

ボタンがタップされたときに起きること

  1. ボタンをタップする(イベント)
  2. ボタンがタップされたことを検知(listen)する
  3. ボタンがタップされたときの処理(ハンドラー)が実行される

アプリをボタンのタップに対応させるには

  • ボタンがタップされたことを検知(listen)するように、ボタンにリスナー(listener)を設置します
  • ボタンへのリスナーの設置には setOnClickListener() メソッドを使います
  • リスナーに、呼び出されたときに実行する処理を記述します

チュートリアル(Unit1)のクリックリスナー(click listener)の例

コードはこんなかんじに書きます

  • ボタンに setOnClickListener() でクリックリスナーを設置します
  • setOnClickListener() の引数は OnClickListener型(インタフェース)です。インタフェースからクラスを作成してインスタンスにしたものを受け取ります
  • OnClickListener インタフェースは、たったひとつ onClick() メソッドを含みます。リスナーがボタンのタップを検知したときに実行する処理を onClick() メソッドに記述(オーバーライド)します。チュートリアルでは rollDice() を実行しています

こんなときにはラムダ式を使うと便利

イベント処理にはラムダ式が便利なの

  • メソッドの引数がインタフェース
  • そのインタフェースが、オーバーライドしないといけないメソッドを1つしか持たない(SAM:Single Abstract Method)
  • 今回の例はこの条件そのまま。なので最終的にコードはとても短く記述できます

実際に setOnClickListener を書き換えてみる

まじめな記述方法

クラスを作成してインスタンス変数を用意してから setOnClickListener にセット

  • インタフェース(OnClickListener)からクラス(ObjC)を作成します
  • クラスからインスタンスを生成して変数(obj)に代入します
  • setOnClickListener() に渡します

ちゃんとしてそう

class ObjC : View.OnClickListener {
    override fun onClick(v: View?): Unit {
        rollDice()
    }
}
val obj = ObjC()
binding.button.setOnClickListener( obj )

クラスを作成して setOnClickListener の引数でいきなりインスタンス化

class ObjC : View.OnClickListener {
    override fun onClick(v: View?): Unit {
        rollDice()
    }
}
binding.button.setOnClickListener( ObjC() )

object を使った記述方法

object をつかうと、作成したクラスからいきなりインスタンスが作れるの

クラス作成と同時にインスタンスを生成してインスタンス変数に代入

  • object 式を利用します。クラス作成と同時にインスタンスを作成できます(無名クラス)
  • 生成されたインスタンスを変数(obj)に代入して利用します
val obj = object: View.OnClickListener {
    override fun onClick(v: View?): Unit {
        rollDice()
    }
}
binding.button.setOnClickListener( obj )

引数部分で直接クラスを作成してインスタンスを生成して渡す

object 式を使ってクラスを作成すると、クラスから生成されたインスタンスが返されます

binding.button.setOnClickListener( object: View.OnClickListener {
    override fun onClick(v: View?): Unit {
        rollDice()
    }
})

ラムダ式を使った記述方法

ラムダ式を使うと、インタフェースから最小限の記述でインスタンスが作れるの

ラムダ式(lambda expression)を使って記述する

  • ラムダ式はインタフェースから最短距離でインスタンスを生成できる記述方法です(ただしインタフェースが一定の条件を満たしている必要があります)
  • Kotlin でのラムダ式の書き方は次の通りです。戻り値はインスタンスです
{ 内部メソッドの引数 -> 内部メソッドの処理 }
  • ラムダ式ではインタフェースの名前やオーバーライドするメソッドの名前など、前後から推測できるものをすべて省略してしまいます
  • 結局、オーバーライドする内部メソッドの引数と、そのメソッドの処理部分だけの記述になります

こんなに短くなるんですね

binding.button.setOnClickListener( { v ->
        rollDice()
} )

ラムダ式で()を省略する

引数がラムダ式だけで メソッド( { ラムダ式 } ) のようになっている場合は ( ) を省略できます

カッコが重ならないので見やすいです

binding.button.setOnClickListener { v ->
    rollDice()
}

ラムダ式で引数を省略する

オーバーライドするメソッドの引数が1つだけの場合、ラムダ式の引数の部分は省略できます。この場合、最終的に処理内容だけの記述になります。次のようになります

ここまですっきり出来ちゃうんですね!

binding.button.setOnClickListener {
    rollDice()
}

処理の中で、省略した引数を参照したいときは it を使います