Kotlin / Programming

ザクっと理解するKotlin Functional (SAM) interfaces

Kotlinの公式文章をもとにfunctional interfaces (関数インターフェース)についてまとめています。
関数インターフェースの宣言方法、SAM変換の説明や使い方を簡単なKotlinコードを用いて説明、解説をしています。

functional interfacesとは

1つの抽象メソッドのみで構成されるインターフェースのことをfunctional interface(関数インターフェース)もしくはSingle Abstract Method (SAM) interfaceと呼びます。
関数インターフェースは非抽象メンバーを持つことはできますが、抽象メンバーは1つのみです。

関数インターフェースはfunを使用して宣言します。

fun interface Interface01 {
    fun function01(): String
}

SAM変換

関数インターフェースは通常のインターフェースのように、クラスが実装可能です。

fun interface Interface01 {
    fun function01(): String
}

class Class01: Interface01 {
    override fun function01(): String {
        return "Hello World"
    }
}

fun main() {
    val class01 = Class01()
    val function01 = class01.function01()
    println(function01) // 結果: Hello World
}

しかしラムダ式を使用すると、より簡潔にコードを書くことができ可読性を高めます。
この書き方をSAM変換と呼びます。

fun interface Interface01 {
    fun function01(): String
}

fun main() {
    val interface01 = Interface01 { "Hello World" }
    println(interface01.function01()) // 結果: Hello World
}

Interface01はパラメータなしでStringを返す抽象メソッドであるfunction01だけで構成されているため関数インターフェースです。
6行目でInterface01のfunction01に対応するラムダ式を使うことでSAM変換を行い、Interface01を動的にインスタンス化しています。

このようにSAM変換を使用すると、Kotlinはインターフェースの単一のメソッドの処理と一致するラムダ式を、インターフェース実装を動的にインスタンス化するコードに変換することができます。

関数インターフェース vs タイプエイリアス

タイプエイリアスでも上記のようにシンプルに書くことができます。

typealias typealiasString = () -> String
val property01: typealiasString = { "Hello World" }

fun main() {
    println(property01()) // 結果: Hello World
}

しかし関数インターフェースとタイプエイリアスは異なる目的のために用意されています。

関数インターフェース
・新しい型を作成する
・特定の関数型インターフェースに対して拡張機能を提供
・複数の非抽象メンバーと1つの抽象メンバーを持つ
・他のインターフェースの実装や拡張が可能

タイプエイリアス
・既存の型の名前であり新しい型を作るわけではない
・1つのメンバーのみ持つ

関数インターフェースの方が柔軟で多くの機能を持っていますが、その反面、特定のインターフェースへの変換作業があるため構文的にも実行時にもコストが多くかかります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です