前言
kotlin官网 (中文版)和kotlin教程学习教程的笔记。
Kotlin中的属性声明必须要有初始化的值
1. get与set
var count: Int? = 0
get
set
val isEmpty: Boolean get() = this.count == 0
2. 属性的后端域变量 ,field 标识符只允许在属性的访问器函数内使用
var name: String? = "" //初始化给定的值将直接写入后端域变量中
get() {
if (field.isNullOrEmpty()) {
return "empty name"
}
return field
}
set(value) {
field = value?.toUpperCase()
}
3. 后端属性
private var _size= 0
val size get() = _size
在内部增删元素时,改动的就是 _size 属性的值;外部只能访问到 size 属性,不能修改 _size 的值。这里的 _size 就叫做「幕后属性」。
4. 常数值 const
如果属性值在编译期间就能确定, 则可以使用 const 修饰符, 将属性标记为编译期常数值(compile time constants). 这类属性必须满足以下所有条件:
- 必须是顶级属性, 或者是一个 object 的成员
- 值被初始化为 String 类型, 或基本类型(primitive type)
- 不存在自定义的取值方法
const val TAG = "KOTLIN"
5. 延迟初始化属性
lateinit var teacher:Teacher
fun setTeacher(){
teacher= Teacher()
}
fun teset(){
println(teacher.toString())
}
这个修饰符只能用于 var 属性, 而且只能是声明在类主体部分之内的属性(不可以是主构造器中声明的属性), 而且属性不能有自定义的取值方法和设值方法. 属性类型必须是非 null 的, 而且不能是基本类型.
在一个 lateinit 属性被初始化之前访问它, 会抛出一个特别的异常, 这个异常将会指明被访问的属性, 以及 它没有被初始化这一错误
6. 属性的覆盖
open class Foo {
open val s:String? = null
}
class Bar1 : Foo() {
override var s: String? = null
get() = super.s
}
class Bar2(override val s: String) : Foo() {
}
可以使用一个 var 属性覆盖一个 val 属性, 但不可以反过来使用一个 val 属性覆盖一个 var 属性. 允许这种覆盖的原因是, val 属性本质上只是定义了一个 get 方法, 使用 var 属性来覆盖它, 只是向子类中添加了一个 set 方法.
后记
函数VS属性
有些情况下, 无参数的函数可以与只读属性相互替代. 虽然它们在语义上是相似的, 但从编程风格上的角度看, 存在一些规约来决定在什么时候应该使用函数, 什么时候应该使用属性.
当以下条件成立时, 应该选择使用只读属性, 而不是使用函数:
- 不会抛出异常
- 复杂度为 O(1)
- 计算过程消费的资源不多(或者在初次运行时缓存了计算结果)
- 多次调用时会返回相同的结果
lateinit vs lazy
val foo by lazy { "foo"}
lateinit var f:String
网友评论