Edited at

Kotlinでread onlyプロパティとinterfaceの関係とか

More than 1 year has passed since last update.

Interfaceではval(read only)で宣言したいけど、それを実装するclassではvar(read/write)、もしくはclass内ではいつでも書き換えできて、外からは参照のみにしたい。といった時のお話。


interfaceとclassのサンプル

interface Player {

val name: String
val weapon: String
val hasSword: Boolean
}

class Fighter : Player {
// 外からはread only
override var name: String
private set
// 外からもread/write
override var weapon: String
// 他のプロパティの状態を参照したread onlyプロパティ
override val hasSword
get() = weapon.contains("剣")

constructor(name: String) {
this.name = name
this.weapon = "片手剣"
}
}


解説


  • Player interfaceでは、すべてvalで宣言

  • Playerを実装するFighterでは、name,weaponはvarに書き換えている

  • weaponはprivate setを使って、Fighterクラス内でのみ書き換え可能にしている(read only)

一部valからvarに宣言を変えているが、これはきちんとコンパイルが通る。interfaceを実装するclassは、read onlyの条件を満たせばよい。つまり、read/writeで宣言しても構わないということなのだろう。


使用例

val fighter = Fighter("ダンジョー")

// これはコンパイルエラー。nameはvarだが、private setなので、外からはsetできない
// fighter.name = "宅麻伸"

// 参照は可能
print(fighter.name)

// weaponは、ただのvarなのでsetできる
fighter.weapon = "両手剣"

// hasWeaponは、valなのでsetできない。そもそも実体は変数ではない
// fighter.hasSword = true

// 参照のみ可能
print(fighter.hasSword)

// Player interfaceに移す
val player: Player = fighter

// これはコンパイルエラー。Playerでは、valで宣言されているのでsetできない
// player.weapon = "炎の剣"

// 参照は可能
print(player.weapon)