カテゴリ: Kotlin 更新日: 2025/12/06

Kotlinの関数型インターフェース(SAM変換)を活用しよう!初心者でもわかる使い方と例

Kotlinの関数型インターフェース(SAM変換)を活用しよう
Kotlinの関数型インターフェース(SAM変換)を活用しよう

先生と生徒の会話形式で理解しよう

生徒

「Kotlinで関数型インターフェースっていう言葉を見たんですけど、何のことか全然わかりません…」

先生

「それはとても大事な概念です!Kotlinでは、Javaと連携するために『関数型インターフェース』という仕組みを使うことがあります。『SAM変換』という機能も関係しています。」

生徒

「SAM変換…?難しそう…」

先生

「大丈夫です!まずは関数型インターフェースの基本から、簡単な例でわかりやすく説明していきましょう。」

1. 関数型インターフェースとは?

1. 関数型インターフェースとは?
1. 関数型インターフェースとは?

関数型インターフェースとは、抽象メソッド(中身が未定義の関数)がちょうど1つだけのインターフェースのことです。英語では「Single Abstract Method(SAM)」と呼ばれますが、ここでは「ひとつだけ約束のあるインターフェース」と覚えれば十分です。

身近なたとえで言うと、「ボタンを押したら1回だけ実行される作業」を約束する係のようなもの。Kotlinでは、主にJava由来のインターフェース(RunnableComparator、各種リスナーなど)をこの形で扱います。

たとえばJavaで有名なRunnable(ルーナブル)は、runという1つだけのメソッドを持ちます。Kotlinからもそのまま使えます。

はじめてのサンプル(動作の流れがわかる最小例)

「ボタンを押したらあいさつする」作業を Runnable で表現してみます。ここでは理解しやすいように、まずは素直な書き方で書いてみましょう。


val work = object : Runnable {
    override fun run() {
        println("こんにちは!作業を1回だけ実行しました。")
    }
}

// 実行してみる(ボタンを押したイメージ)
work.run()

ポイントは、run() という「1回だけの仕事」を約束していること。たった1つの抽象メソッドだから、何をすればよいかがシンプルに伝わります。まずは「ひとつの仕事を渡す入れ物」としてイメージしておくと理解が進みます。

このように、関数型インターフェースは「ひとつの仕事を表す型」として扱えるので、イベント処理や並行処理などで大活躍します。Kotlinではこの考え方をベースに、より書きやすく表現する方法も用意されていますが、まずは「抽象メソッドが1つだけ」という核をしっかり押さえておきましょう。

2. SAM変換ってなに?

2. SAM変換ってなに?
2. SAM変換ってなに?

SAM変換(Single Abstract Method 変換)とは、関数型インターフェースをKotlinのラムダ式(無名関数)として書き換えられる機能です。

つまり、「new Runnable() { ... }」のようなJavaの書き方を、Kotlinではもっと簡単な書き方にできる仕組みです。

これにより、コードがすっきりして読みやすくなります。

3. 実際にSAM変換を使ってみよう(Runnableの例)

3. 実際にSAM変換を使ってみよう(Runnableの例)
3. 実際にSAM変換を使ってみよう(Runnableの例)

たとえば、Javaでは次のようにスレッド処理を書くことがあります:


val thread = Thread(object : Runnable {
    override fun run() {
        println("スレッドが動きました!")
    }
})
thread.start()

これをKotlinのSAM変換を使って書くと、次のようにラムダ式だけで済みます。


val thread = Thread {
    println("スレッドが動きました!")
}
thread.start()

とてもすっきりしていますよね!これがKotlinのSAM変換の威力です。

4. KotlinでSAM変換が使えるケースと使えないケース

4. KotlinでSAM変換が使えるケースと使えないケース
4. KotlinでSAM変換が使えるケースと使えないケース

SAM変換が使えるのは、Javaから来たインターフェースに対してだけです。Kotlinで定義したインターフェースにはSAM変換は使えません。

つまり、RunnableやComparatorなど、Javaのクラスを扱うときにSAM変換が便利なんです。

5. Comparator(比較のためのインターフェース)もSAM変換できる

5. Comparator(比較のためのインターフェース)もSAM変換できる
5. Comparator(比較のためのインターフェース)もSAM変換できる

もう一つの例として、Comparatorを見てみましょう。

これは、2つの値を比べるための関数型インターフェースです。Java風の書き方ではこうなります:


val comparator = Comparator { a: Int, b: Int ->
    a - b
}
val result = comparator.compare(5, 3)
println(result) // 出力: 2(5 - 3)

このように、Kotlinではラムダを使って簡単に書けます。

6. 自分でSAM変換用のインターフェースを作ることはできる?

6. 自分でSAM変換用のインターフェースを作ることはできる?
6. 自分でSAM変換用のインターフェースを作ることはできる?

基本的に、Kotlinのコードで作ったインターフェースにはSAM変換は適用されません

ですが、@FunctionalInterfaceというアノテーションをJavaで付けたインターフェースなら、KotlinでもSAM変換が使えます。

これはあくまでJavaとKotlinの連携で使われる仕組みだと覚えておきましょう。

7. SAM変換を使うとコードがスッキリする

7. SAM変換を使うとコードがスッキリする
7. SAM変換を使うとコードがスッキリする

KotlinのSAM変換を使うと、Javaのような「インターフェースの匿名クラス」を毎回書かなくてもよくなります。

これにより、コードの読みやすさや保守性が大幅に向上します。

初心者のうちは、どちらの書き方も見かけるかもしれませんが、Kotlinらしい書き方(ラムダ式)に慣れていきましょう。

8. SAM変換と高階関数の違いは?

8. SAM変換と高階関数の違いは?
8. SAM変換と高階関数の違いは?

SAM変換はJavaの関数型インターフェースをKotlinでラムダとして使うテクニックです。一方で、高階関数は「関数を引数にする関数」のことで、Kotlinの言語機能です。

似たような見た目でも、使われる場面や目的が異なります。混同しないようにしましょう。

9. よくある疑問:SAM変換を使わないとどうなる?

9. よくある疑問:SAM変換を使わないとどうなる?
9. よくある疑問:SAM変換を使わないとどうなる?

もしSAM変換を使わずに書こうとすると、毎回「object : Runnable { override fun run() { ... } }」のような冗長なコードを書く必要があります。

そのため、コードが長くなって読みづらくなり、初心者にとっては理解しにくくなるでしょう。

まとめ

まとめ
まとめ

Kotlinにおける関数型インターフェースとSAM変換の仕組みは、Javaとの連携において非常に重要な役割を果たします。本記事では、関数型インターフェースの定義から始まり、SAM変換によってラムダ式を使った簡潔な記法が可能になることを、RunnableComparatorの具体例を通して丁寧に解説しました。
特に、Java由来のインターフェースに対してのみSAM変換が適用されるという点は、Kotlin特有の仕様として押さえておくべきポイントです。Kotlinで定義されたインターフェースに対しては、SAM変換は効かないため注意が必要です。
SAM変換は、Kotlinの「ラムダ式」と組み合わせることで、コードをより簡潔に、美しく保つための強力な武器となります。冗長なクラス宣言や匿名オブジェクトを避け、関数型らしい設計が可能になるため、コードの保守性や可読性も向上します。
また、SAM変換と高階関数の違いにも注意が必要です。見た目が似ていても、それぞれの機能の目的や使いどころは異なります。高階関数はKotlin言語そのものの機能であり、関数を引数に渡す設計が自然に行えます。一方でSAM変換は、Javaの関数型インターフェースをラムダ式で表現する手段です。
Kotlinを学ぶ上で、Javaとの相互運用性は避けて通れない重要テーマです。だからこそ、SAM変換の理解はKotlinエンジニアとしての第一歩と言えるでしょう。今後は、標準ライブラリやAndroid開発でもこの知識が活きてきます。

補足:SAM変換を使った関数型インターフェースの活用例

以下のように、Javaライブラリと連携するコードではSAM変換を使うことでコードが非常にシンプルになります。


fun executeTask(task: Runnable) {
    task.run()
}

fun main() {
    // SAM変換により、Runnableの実装をラムダ式で書ける
    executeTask {
        println("タスクを実行しました!")
    }
}

このように、SAM変換を使うことで、Javaの書き方をそのまま書かずに済み、Kotlinらしい書き方が可能になります。

先生と生徒の振り返り会話

生徒

「なるほど〜、SAM変換ってJavaのインターフェースをKotlinで簡単に書けるようにする仕組みなんですね!」

先生

「その通り!KotlinはJavaと連携しやすいように、こうした便利な機能が備わっているんですよ。」

生徒

「RunnableやComparatorの例を見て、コードがすごくすっきりするのがわかりました!あと、高階関数との違いもちゃんと理解できました!」

先生

「素晴らしいですね。今後は、ライブラリを使うときにもSAM変換を意識して書いていくと、Kotlinらしいコードが書けますよ。」

生徒

「はいっ!これからはSAM変換を活用して、もっと読みやすいコードを目指していきます!」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Kotlinの関数型インターフェースとは具体的にどんな特徴がありますか?

Kotlinの関数型インターフェースは、1つだけ抽象メソッドを持つJavaのインターフェースを指します。KotlinではJavaと連携する際に、関数型インターフェースをラムダ式として使える特徴があります。
関連記事:
カテゴリの一覧へ
新着記事
Go言語の構造体でインターフェースを実装する方法を初心者向けにやさしく解説!
Kotlinの演算子一覧と使い方!算術・比較・論理演算子の基本を解説
Go言語の文字列フォーマット!fmt.Sprintfで簡単に出力を整形する方法
Go言語のエラーと例外の違いを初心者向けに整理!わかりやすく解説
人気記事
No.1
Kotlin・Go・Swift記事の人気No1
Swiftのwhile文とrepeat while文を完全マスター!初心者にもわかる繰り返し処理の使い方と違い
No.2
Kotlin・Go・Swift記事の人気No2
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.3
Kotlin・Go・Swift記事の人気No3
Swift入門ガイド|基本構文と書き方をマスターしよう
No.4
Kotlin・Go・Swift記事の人気No4
Kotlinの正規表現(Regex)の使い方をやさしく解説!文字列操作の基本を初心者向けに学ぼう
No.5
Kotlin・Go・Swift記事の人気No5
Kotlinで画面を作る!レイアウトXMLとビューの基本操作をやさしく解説
No.6
Kotlin・Go・Swift記事の人気No6
Kotlinのコンパニオンオブジェクトとは?初心者向けに使い方と役割をわかりやすく解説!
No.7
Kotlin・Go・Swift記事の人気No7
Kotlinのwhen式を完全ガイド!初心者でもわかるパターンマッチング的な使い方
No.8
Kotlin・Go・Swift記事の人気No8
Swiftのオプショナル型とは?初心者でもわかる使い方とアンラップの基礎