拡張関数
既存のクラスを継承せず、クラス外で定義しながらもそのクラスのメソッドとして呼び出せる構文。OOP 的な呼び出しスタイルと、FP 的な「後から操作を追加できる」柔軟性を両立する。
Kotlin での例:
// クラス外で定義するが、メソッド構文で呼べる
fun Shape.area(): Double = when (this) {
is Circle -> PI * radius * radius
is Rectangle -> width * height
}
shape.area() // OOP的な構文で呼べる
OOP と FP の中間解
| 観点 | OOP メソッド | 拡張関数 | FP 関数 |
|---|---|---|---|
| 定義場所 | クラス内 | クラス外 | 独立 |
| 呼び出し構文 | shape.area() |
shape.area() |
area(shape) |
| 後から追加 | 難しい | 可能 | 可能 |
Expression Problemの「操作追加」側を楽にしつつ、レシーバー構文(shape.area())を維持できる。
スコープ関数との組み合わせ
Kotlin ではスコープ関数(let, run, also 等)を使うと、パイプ的な記述も可能:
shape
.let { calculateArea(it) }
.let { formatResult(it) }
言語サポート
- Kotlin:
fun Type.methodName()で定義 - C#:
staticメソッドにthisパラメータを付ける - Swift:
extensionで既存型に機能追加 - TypeScript/JavaScript: プロトタイプ拡張(非推奨)、または単純な関数
関連
- 関数型プログラミング - FP の操作追加の柔軟性
- Expression Problem - 拡張関数が解決する問題
- 関数適用スタイル - レシーバー構文とデータ起点の思考
- 主語の位置:OOPと関数型における関数適用スタイルの違い - 詳細な比較