美文网首页KotlinKotlin专题Kotlin
Kotlin学习之属性和字段

Kotlin学习之属性和字段

作者: 等风来_Android | 来源:发表于2018-05-09 10:15 被阅读24次

今天开始kotlin第三节内容:属性和字段
1,声明属性:
Kotlin中的属性可以用var声明为可变的,也可以用val声明为只读的

class Address{
var name : String= "Tom"
var age : Int= 0
var sex : String? 
}

要使用一个属性,只要用名称引用它即可

class CopyAddress(name : String) : Address{
val address= Address();//创建对象
var name= address.name//将调用访问器
var age : Int= address.age

}

2,Getters 与 Setters
a:声明一个属性的完整语法是:

var 属性名:属性类型 = 初始化器
getter方法
setter方法
。。。。。。。。。
其中初始化器,getter,setter方法都是可选的,如果属性的返回值类型可以从初始化器或者getter方法推断出来,则可以省略
var allByDefault: Int? // 错误:需要显式初始化器,隐含默认 getter 和 setter
var age = 20//类型int,默认getter,setter方法

b:自定义getter,setter

var stringResponding : String
get()= this.toString()
set(value){
setDataFromString(value) // 解析字符串并赋值给其他属性
}

3,幕后字段
kotlin 中类不可以有字段 , 但是使用自定义访问器时 , kotlin 提供了一个自动幕后字段 , 通过 field 访问
field 幕后字段只可以在自定义访问器中使用

var a = 12//初始值会直接赋值给幕后字段field
get(){
//直接引用field做判断
return if(field >=0) field else -field
}
set(value){
//使用传入的值做判断
if(value>100){
println("赋值大于100,默认的field还为 $field")
}
}else{
field = value
printin("赋值成功:$field")
}

4,幕后属性
通过默认 getter setter 访问私有属性会被优化 , 不会引入函数调用开销

private var _map: Map<String, Int>? = null
public val map: Map<String, Int>
    get() {
      if(_map == null){
        _map = HashMap() // 类型推断
      }
      return _map ?: throw AssertionError("Set to null by another thread")
    }


5,延迟初始化属性与变量
一般情况下 , 属性声明为非空类型必须要在构造函数中初始化 , 然而 , 属性可以通过依赖注入初始化 , 或者可以通过单元测试 setu() 初始化

这种情况下 , 不能在构造函数中提供非空的初始化器 , 又想在引用时避免空检查

就可以使用 lateinit 延迟初始化属性和变量

class Person{
  lateinit var name: String
  //通过setup方法或者注解等初始化
  @Setup fun setUp(){
    name = "tim"
  }
  @Test
  fun show(){
    print(name) // 因为 name 是 String非空类型 , 所以此时调用就避免了空检查 , 打印 tim
  }
}
注意
1.lateinit 只能用于类体中的属性,不能是主构造函数中的属性,也不能有自定义访问器getter setter
2.kotlin1.2之后,可以用于顶层属性和局部变量
3.该属性必须是非空类型,不能是原生类型
4.该属性初始化之前访问,会抛出异常UninitializedPropertyAccessException


6,检测一个lateinit var是否已经初始化
Kotlin1.2 之后可以 检测一个 lateinit var 是否已经初始化

只需要在该属性的引用上使用 .isInitialized

class Person {
    lateinit var name: String
    fun show(){
        if(::name.isInitialized){
            print(name)
        }else{
            println("name 还未初始化")
        }
    }
}


相关文章

网友评论

    本文标题:Kotlin学习之属性和字段

    本文链接:https://www.haomeiwen.com/subject/omqnrftx.html