【Kotlin】委譲プロパティ (Delegated Properties)について
目次
- [委譲プロパティ (Delegated Properties)とは](#委譲プロパティ (Delegated Properties)とは)
- 委譲とは
- 標準ライブラリ
- まとめ
- 参考にさせていただいたサイトなど
委譲プロパティ (Delegated Properties)とは
- クラスのプロパティ(メンバ)のsetter/getter処理を別のオブジェクトに移譲する仕組み
- ここで私は、移譲とはというのがまだ理解できてないレベルでした。
- byを使うことで、委譲する先を指定できます。
委譲とは
-
委譲 (delegation) とはオブジェクト指向プログラミングにおいて、あるオブジェクトの操作を一部他のオブジェクトに代替させる手法のこと。
(wikipedia参照) -
例
- クラスBで処理を、クラスAのオブジェクトに委譲している。
Sample.kt
class A {
fun foo {
println("hoge")
}
}
class B {
// クラスBは、hogeの処理をクラスAに委譲している。
fun hoge {
val a = A()
a.foo()
}
}
標準ライブラリ
delegated propertiesの標準ライブラリとしては、lazyとObservableなどがあります。
その他、NotNullなどがありますが、こちらはまだよく分かってないです。
lazy
lazyは、プロパティの初期化を初めて参照された時まで遅延できます。
-
何が嬉しいか
- AndroidのContextなど、onCreate以降にしか参照できないもののプロパティをオプショナルにしなくて済む
- オプショナルだと、
?
や!!
などの記述が増えるし、nullの可能性も出てきてしまうので確認などが必要になる。
-
例
- 現在時刻を値として持つ、プロパティ。
- 初期化されたタイミングの時間の値を持ち、immutableなので変更不可。
import java.time.LocalDateTime
val lazyProperty: String by lazy {
val dateAndtime: LocalDateTime = LocalDateTime.now()
"Current date and time: $dateAndtime"
}
fun main(args: Array<String>) {
println(LocalDateTime.now())
println(lazyProperty)
println(lazyProperty)
==> 結果
2020-09-06T21:56:21.118270
Current date and time: 2020-10-06T21:56:21.118703 => 前のDataTimeより後の時間になっている。
Current date and time: 2020-10-06T21:56:21.118703 => 同じ値
}
- lateinitとの違い
- lateinitでも同じことを実現できますが、lateinitはmutable(あとで、値を変更できる)、lazyはimmutable(初期化した値から変更できない)という違いがあります。
Observable
Observableは、プロパティの値の変更を検知して、それに伴って処理を実行できるというものです。
- 例
Observable.kt
var observableName: String by Delegates.observable("Jonathan") {
property, old, new -> println("$old to $new")
}
fun main(args: Array<String>) {
observableName = "Joseph" => 結果 "Jonathan to Joseph"
observableName = "Jotaro" => 結果 "Joseph to Jotaro"
}
まとめ
-
委譲プロパティとは
- プロパティのsetter/getter処理を別のオブジェクトに移譲する仕組み
-
標準ライブラリの2つある。
- lazyとは、プロパティの初期化を参照されたタイミングまで遅延できる。
- observableとは、値の変更を検知して処理を実行できる