(1)自定义属性访问器:
所谓自定义属性访问器顾名思义,在我们定义属性的时候,比如定义一个变量属 性再给它附上相应的值,如果要调出这个变量属性的值或者更改它的值,就需要使用系统默认实现的 getter 和 setter方法,如果不想要使用系统默认的getter和setter方法就需要我们的自定义访问器;
自定义访问器的机制:
自定义访问器会在你定义一个属性没有初始化属性对象的时候得到触发可以调用 的环境,
正如:val str: String
这就是一个没有初始化的变量,当你定义了一 个类似这种的属性变量时,系统就会提示你初始化这个属性或者使用其他方法让 其不需要初始化,比如将定义这个属性的外层类声明为抽象的 abstract,那你既 不想使用系统的setter 和 getter方法,又不想声明为抽象的,那么就可以使用 我们的自定义访问器:
如: class A(){
// 这里时一个没有初始化的对象 val str: String
// 这是自定义的get ,当你调用str对象,想要得到这个对象的值时,就会调用get放回
// "nihao" 这个值 get() { return "nihao" } }
// 自定义set ,需要为变量的可更改的类型
var nihao: String
set(value: String) {
nihao = value
}
get() { return nihao }
注意:只有在构造方法或者类中声明属性才可以使用getter setter普通方法不可以。
(2)知识扩展:
field 关键字
“幕后字段”backing field 幕后字段是用来解决同时定义
getter setter
产生的自我调用造成内存溢出异常(java.lang.StackOverflowError )而出现的,当你使用get调用当前属性的值时,
系统就会自动帮你同时调用set ,既然调用了Set 由于set中需要获取属性的引用才可以重写赋值,着就等于get,set
被调用一次之后会无限的进行循环重复的调用操作。
如:
class People {
var name: String get() = name set(value) { name = value }
}
所以,就出现了field 幕后字段,field 字段相当于当前 get,set所拥有的局部字段,其他地方不可使用这个字段。
如:
class People {
var name: String = "Mike" get() = field set(value) { field = value }
}
那么field是如何让get,set不会重复调用的呢,很简单,在set存入值时,set会将值存入field字段中不会调用到自身的引用,
而get取值时,get是取出field中的值,也不会去调用到自身的引用,所以get,set在进行操作时就不会出现循环调用自身的情况,
异常也就不会发生了。
(3)修改访问器的可见性
class LengthCounter{
var counter: Int = 0 private set // 不能在类外部修改这个属性
}
(4)lateinit 修饰符:
这个修饰符表示这个属性将会把初始化延迟到构造方法被调用后 lateinit var a:String
网友评论