ここでは、Kotlin でクラスに実装するプロパティについてまとめています。
バッキングフィールド(backing field)とカスタムゲッター(custom getter)という仕組みがあります。
プロパティとバッキングフィールド(backing field)
Kotlin でプロパティをクラスに定義する場合、以下のように記述できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class Person { private var _text: String = "" private var _number: Int = 0 var name: String get() { return _text } set(value) { _text = value } var age: Int get() { return _number } set(value) { _number = value } } |
この Person クラスでは、name と age というプロパティを公開しています。
プロパティの値はそれぞれ、_text と _number というメンバー変数に格納されています。
※修飾子 private を付けることで、_text, _number は外部から直接アクセスできなくなります。
このように、あるプロパティの値を保持するオブジェクト(今回はメンバー変数)のことを、
バッキングフィールド(backing field)といいます。
プロパティ名と型宣言に続く get() や set(value) で、バッキングフィールドの値を参照したり、値を代入したりすることができます。
プロパティの参照・代入で自由度の高い処理を実装できる get() や set(value) のことを、
カスタムゲッター(custom getter)、カスタムセッター(custom setter)と呼びます。
この Person クラスは、以下のようにプロパティを変更、参照できます。
1 2 3 4 5 6 7 8 |
fun main() { val taro = Person() taro.name = "太郎" taro.age = 35 println("${taro.name}") // 太郎 println("${taro.age}") // 35 } |
自動生成されるバッキングフィールド(backing field)
Kotlin では、バッキングフィールドを明示的に記述しなくても、必要に応じて自動生成されます。
上記の Person クラスのコードは、Kotlin では以下のようにも記述できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Person { var name: String = "" get() { return field } set(value) { field = value } var age: Int = 0 get() { return field } set(value) { field = value } } |
自動的に生成されるバッキングフィールドへは、キーワード field を使ってアクセスします。
また、プロパティの初期値を設定する必要があります。
プロパティとカスタムゲッター(custom getter)
Kotlin では、バッキングフィールドが自動で生成されますが、バッキングフィールドを持たないプロパティを定義することも可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Person { var name: String = "" get() { return field } set(value) { field = value } val nameLength: Int get() { return this.name.length } } |
プロパティ nameLength は val で定義されており、バッキングフィールドを持ちません。
代わりに、カスタムゲッター(custom getter)だけを持ちます。
参考
var と val の違いについては、「変数の定義valとvar」にまとめています。
カスタムゲッターは、以下のように省略して記述することも可能です。
1 2 3 |
val nameLength: Int get() = this.name.length |