主构造函数、次构造函数
性针对定义的每一个属性,kotlin都会产生一个field、一个getter、一个setter,field用来存储属性数据,你不能直接定义field,kotlin会封装field,保护它里面的数据,只会暴露给getter和setter使用,属性的getter方法决定如何读取属性值,每个属性值都有getter方法,setter方法决定如何给属性赋值,所以只有可变属性才有setter方法,尽管kotlin会自动提供默认的getter和setter方法,但在需要控制如何读写属性数据时,你也可以自定义他们
//小括号中为主构造函数变量
class Player(
_name:String, //临时变量 可以使用 _ 开头
_age:Int = 10,//添加默认值
_isNormal:Boolean
) {
//次构造函数一个参数 使用constract
constructor(_name: String) : this(_name, age = 10, isNormal = true)
//次构造函数两个参数 使用constract
constructor(name: String, age: Int) : this(name, age, isNormal = true) {
this.name = name.toUpperCase()
}
var name = _name
//自定义 get set方法
get() = field.capitalize()
set(value) {
field = value.trim()
}
var age = _age
//自定义 get set方法
get() = field+1
set(value) {
field = value*2
}
//初始化块--可以设置变量或者值,以及执行有效性检查,如检查传给某构造函数的值是否有效
//初始化块代码会在构造类实例时执行
init {
//先决条件函数 如果条件不满足 执行后边的lambda表达式
require(age > 0) {
"age must be positive"
}
require(_name.isNotBlank()) {
"player must have a name"
}
}
//延迟初始化
//使用lateinit关键字相当于做了一个约定,在用它的之前负责初始化
//只要无法确认lateinit变量是否完成初始化,可以执行isInitialized检查
lateinit var str: String
//执行初始化
fun ready() {
str = "123";
}
//调用时判断是否初始化过
fun show() {
if (::str.isInitialized) print(str)
}
}
初始化顺序
- 1.主构造函数
- 2.类级别的属性赋值
- 3.init初始化块里的属性赋值和函数调用
- 4.次构造函数里的属性赋值和函数调用
//在init的前边才可以
private val blood = 100
//使用初始化块的时候,顺序很重要,必须保证块中的所有属性已经完成初始化
init {
//4倍
val bloodBonus = blood.times(4)
}
private val name:String
fun firstLetter() = name[0]
//使用初始化块的时候,顺序很重要,必须保证块中的所有属性已经完成初始化
init {
//要在print方法调用之前进行初始化
name = "jack"
print(firstLetter())
}
//需要放在initplayerName之前初始化
val name = _name
val playerName: String = initPlayerName()
fun initPlayerName() = name