Kotlinでクラス内からだけ変更可能なプロパティを定義する

Kotlinで、クラス外部からは変更不可なプロパティとして見えて、クラス内部からは変更可能なプロパティを定義する方法を説明します。

いきなり結論

class Person {
    private var _name = "Tom"
    val name get() = _name
}

このように書くと、クラス内部からは_nameを使うことで変更可能なプロパティとして扱うことができますが、クラス外部からは変更不可なnameしか見えなくなります。

Kotlinのプロパティ定義

説明するまでもないかもしれませんが・・・

Kotlinのプロパティは、varで定義すると変更可能に、valで定義すると変更不可になります。また、privateで宣言するとクラス内部からだけアクセスできます。

上記の例では、

private var _name

はクラス内部からだけアクセスできる変更可能なプロパティです。

一方、

val name

はクラス外部からもアクセス可能ですが、変更不可です。

カスタムゲッター

さて、private var _nameval nameを定義しただけでは、これらは別々のプロパティです。_namenameを結び付けるのが、

get() = _name

の部分です。これはカスタムゲッターです。

カスタムゲッターはプロパティ名に続けてget()で定義し、そのプロパティを読みだしたときの処理を定義します。シンプルに値を返すだけなら、この例のように

get() = ...

の形で書くことができます。もっと複雑な処理をさせたい場合は、

get() {
   ...
   return ...
}

のように関数の形で書くこともできます。

さて、最初の例に戻りましょう。

private var _name = "Tom"
val name get() = _name

この例では、nameのカスタムゲッターが、_nameを返しています。つまり、nameを読みだすと、_nameの値が取得されるということです。これで、name_nameの実体が同じ文字列になります。

このようにして、クラス内部からは変更可能、クラス外部からは変更不可能なプロパティを定義することができます。

ちなみに、カスタムセッターというものもあります。値をセットするときに呼び出す処理を書くことができます。当然ながらカスタムセッターは、varで定義したプロパティにだけ、定義することができます。valで定義したプロパティはカスタムセッターを持つことはできないので、nameにもカスタムセッターは不要です。