Kotlin的类可以有属性。 属性可以用关键字var声明为可变的,否则使用只读关键字val。
Getters 和 Setters
声明一个属性的完整语法:
var <propertyName>[: <propertyType>] [= <property_initializer>] [<getter>] [<setter>]
其初始器(initializer)、getter 和 setter 都是可选的。
属性类型如果可以从初始器 (或者从其 getter 返回值)中推断出来,也可以省略。
一个只读属性(val声明)的语法和一个可变的属性的语法有两方面的不同:
1、只读属性用val开始代替var。
2、只读属性不允许 setter。
实例:
class Address(province: String) { var country: String = "China" var province: String = province get() = field.toUpperCase() set(value) { field = value } var city: String = "sanmenxia" var district: String = "hubin" var street: String? = null get() = field.toString() set(value) { field = value } //一个只读属性的语法和一个可变的属性的语法有两方面的不同: // 1、只读属性的用val开始代替var // 2、只读属性不允许setter // 自定义getter方法 val isEmpty: Bollean get() = this.country.count() == 0 var counter: Int = 0 set(value) { if(value >= 0) { field = value } } }
调用方法:
val address= Address("henan")
Log.d("alen","address is " +address.isEmpty + ",province is " +address.province)
address.province = "guangdong"
Log.d("alen","province is " + address.province)
address.street = "大岭路"
Log.d("alen","street is " + address.street)
Log.d("alen","counter111 is " + address.counter)
address.counter = 7
Log.d("alen","counter222 is " +address.counter)
幕后字段Backing Fields
address.street = "大岭路"
Log.d("alen","street is " + address.street) Log.d("alen","counter111 is " + address.counter) address.counter = 7 Log.d("alen","counter222 is " +address.counter)
Kotlin 中类不能有字段。然而,当使用自定义访问器时,有时有一个幕后字段(backing field)有时是必要的。为此 Kotlin 提供 一个自动幕后字段,它可通过使用field标识符访问。
field标识符只能用在属性的访问器内。
幕后属性Backing Properties
如果Backing Fields不适用的话,其实可以直接使用返回属性就可以了。
private var _table: Map<String, Int>? = null public val table: Map<String, Int> get() { if(_table == null) { _table = HashMap() } return _table ?: throwAssertionError("Set to null by another thread") }
延迟初始化属性
一般地,属性声明为非空类型必须在构造函数中初始化。 然而,这经常不方便。例如:属性可以通过依赖注入来初始化, 或者在单元测试的 setup 方法中初始化。 这种情况下,你不能在构造函数内提供一个非空初始器。 但你仍然想在类体中引用该属性时避免空检查。
为处理这种情况,可以用lateinit修饰符标记该属性。
该修饰符只能用于在类体中(不是在主构造函数中)声明的var属性,并且该属性不能有自定义 getter 或 setter。该属性必须是非空类型,并且不能是 原生类型。
在初始化前访问一个lateinit属性会抛出一个特定异常,该异常明确标识该属性 被访问及它没有初始化的事实。