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)