プロパティの宣言
クラスのボディに「val」キーワードで宣言すると読取り専用で、
「var」キーワードで宣言すると変数としてプロパティを宣言できます。
プロパティは必ず初期化しないといけません。初期化は「プロパティイニシャライザ」か「イニシャライザブロック」で行います。
fun main(args: Array) {
val suzuki = Student("suzuki", 80.0)
// nameは読取り専用なので変更できない
// 下記のコードはビルドエラー
// suzuki.name = "tanaka"
suzuki.score = 70.0
println("name = ${suzuki.name}")
println("score = ${suzuki.score}")
println("note = ${suzuki.note}")
}
class Student(name: String, score: Double) {
val name = name
var score = score
// プロパティは必ず初期化しないといけない
// 次のコードはビルドエラーになる
// val desc: String
var note: String
init {
// イニシャライザブロックで初期化してもOK
note = "None"
}
}
name = suzuki
score = 70.0
note = None
ゲッター/セッター
プロパティはゲッター/セッターを持ちます。
上記の例でもインスタンス「suzuki」からプロパティ「score」に値をセットしています。
直接値をセットしているように見えますが、実際にはデフォルトセッターを通じて値がセットされている状態です。
値を取得している部分も、デフォルトゲッターを通じで値を取得しています。
カスタムゲッター/セッターを作成するには「get」「set」を利用します。
カスタムゲッター/セッター内で、そのプロパティ自身にアクセスするには「field」を利用します。
これを「バッキングフィールド」といいます。
(カスタムゲッター/セッターで、自分自身にアクセスするのに自分のプロパティ名を利用すると、
無限にゲッター/セッターを呼び出すことになりスタックオーバーフローになります。
例えば、nameゲッター内でreturn nameとすると再びnameゲッターを呼ぶことになります。
するとnameゲッターでnameゲッターを呼び、またそのnameゲッターでnameゲッターを呼び…
と無限に呼び出してしまします)
fun main(args: Array) {
val suzuki = Student("suzuki", 80.0)
suzuki.score = 70.0
suzuki.score = -10.0
println("name = ${suzuki.name}")
println("score = ${suzuki.score}")
println("note = ${suzuki.note}")
}
class Student(name: String, score: Double) {
val name = name
get() = field.toUpperCase()
// nameは読取り専用なので、setterを作成することはできない
var score = score
get() = field / 100.0
set(value) {
if (value < 0.0 || 100.0 < value) {
return
}
field = value
}
var note: String
init {
note = "None"
}
}
name = SUZUKI
score = 0.7
note = None
また、必要に応じてゲッター/セッターにもヴィジビリティ修飾子やアノテーションを指定することができます.
fun main(args: Array) {
val suzuki = Student("suzuki", 80.0)
// scoreセッターはprivateなので、以下はビルドエラーになる
// suzuki.score = 70.0
// suzuki.score = -10.0
println("name = ${suzuki.name}")
println("score = ${suzuki.score}")
println("note = ${suzuki.note}")
}
class Student(name: String, score: Double) {
val name = name
get() = field.toUpperCase()
var score = score
get() = field / 100.0
private set(value) {
if (value < 0.0 || 100.0 < value) {
return
}
field = value
}
var note: String
init {
note = "None"
}
}
name = SUZUKI
score = 0.8
note = None