數據類是真的沒有爲此做出。由於它們的屬性必須在主構造函數中聲明,所以您無法真正向它們添加自定義行爲。這就是說,如果你必須的話,你可以通過複製屬性來實現這一點,然後使用自定義設置器或者Delegates.observable
。
這裏是一種定製的setter方法來做到這一點,在這裏你會被訪問的公開可見name
和age
屬性,守在構造函數中聲明的那些最新的,以及:
data class Person(private var _name: String, private var _age: Int) {
var name = _name
set(value) {
println("Name changed from $name to $value")
field = value // sets the backing field for `name`
_name = value // sets the `_name` property declared in the primary ctor
}
var age = _age
set(value) {
println("Age changed from $age to $value")
field = value
_age = value
}
}
同樣的想法,與Delegates.observable
,其中做了一些工作的你,在這裏你只開銷設置在構造函數聲明爲新值的屬性:
data class Person(private var _name: String, private var _age: Int) {
var name: String by Delegates.observable(_name) { prop, old, new ->
println("Name changed from $old to $new")
_name = new
}
var age: Int by Delegates.observable(_age) { prop, old, new ->
println("Age changed from $old to $new")
_age = new
}
}
任的T用法HESE看起來像這樣(的toString
看起來有點醜與下劃線):
val sally = Person("Sally", 50)
println(sally) // Person(_name=Sally, _age=50)
sally.age = 51 // Age changed from 50 to 51
println(sally) // Person(_name=Sally, _age=51)
println(sally.name) // Sally
println(sally.age) // 51
編輯回答以下問題:
如果您並不需要你的類是數據類,下面很可能是最簡單的辦法:
class Person(name: String, age: Int) {
var name: String by Delegates.observable(name) { _, old, new ->
println("Name changed from $old to $new")
}
var age: Int by Delegates.observable(age) { _, old, new ->
println("Age changed from $old to $new")
}
}
這樣,你仍然有一個構造函數名稱的年齡作爲參數,但它們被分配到類內部的屬性。這是不可能的與數據類,因爲一個數據類的每一個構造參數必須是一個屬性,以及(標val
或var
)。欲瞭解更多,您可以看到constructors,properties,並data classes的文檔。
你的數據類的例子並不編譯 – voddan
有*當一個普通班不能代替數據類的無*這樣的情況。只是說。 – voddan