1、Kotlin field 关键字
//TODO Kotlin 定义类与field关键字学习
class KtBase {
var name = "zhangsan"
/*虚拟机做的事
@NotNull
private String name = "zhangsan"
public void setName(@NotNull String name){
this.name = name;
}
@NotNull
public void getName(){
return this.name;
}
*/
var value = "ABCDEFG"
//写不写, 虚拟机都会生成下面的代码
get() = field
set(value) {
field = value
}
var info = "adsdsad ok is success"
get() = field.capitalize() //把首字母变大写
set(value) {
field = "**{$value}**"
}
/*
背后做的事
private String info = "adsdsad ok is success";
public void setInfo(@NotNull String info){
this.info = "**{$value}**"
}
@NotNull
public void getInfo(){
return StringKT.capitalize(this.info);
}
*/
}
fun main() {
KtBase().name = "lisi" //逻辑是 new KtBase() .setName ,所有虽然虚拟机里是private,这个地方也可以操作
println(KtBase().name)//逻辑是new KtBase() .getName
println("<<<<<<<<<<<<")
println(KtBase().info)
KtBase().info = "wangwu"
}
2、Kotlin竟态防范条件.also
//TODO Kotlin 计算属性 与防范静态条件
class KTBase {
val number: Int = 0
//计算属性,下面这样写覆盖了get()函数 ,覆盖了field本身
val number2: Int
get() = (1..1000).shuffled().first()//从1到1000取出随机值
val info: String? = /*null*/ ""
// 防范竟态条件,当你调用这个成员可能为null,就必须采用防范竟态条件
fun getShowInfo(): String {
//这种就是防范静态条件
return info?.also {
"最终info结果是:$this"
} ?: "你原来是null,请检查代码"
}
}
fun main() {
println(KTBase().number)
// KTBase().number = 9;//报错,是因为没有set函数,var有seT函数
println(KTBase().number2)
}
3、Kotlin主构造函数
//TODO Kotlin 主构造函数
//主构造函数 规范说都是加_xxx的方式,临时输入类型,不能直接用,需要接收
//_name等等。都是临时类型,不能直接用,需要主构造函数
class KtBase(_name: String, _sex: Char, _age: Int, _info: String) {//主构造函数
var name = _name
get() = field //get不允许私有化
private set(value) {
field = value
}
val sex = _sex
val age = _age
get() = field + 1
val info = _info
get() = "[${field}]"
fun show() {
println(name)
println(sex)
println(age)
println(info)
}
}
fun main() {
val p = KtBase(_name = "张三", _info = "学习KT语言", _age = 27, _sex = 'M')
p.show()
}
4、Kotlin里主构造函数里定义属性
//TODO Kotlin 主构造函数
//一步到位,比较常用 var name:String 相当于var name = _name
class KtBase(var name: String, val sex: Char, val age: Int, var info: String) {//主构造函数
fun show() {
println(name)
println(sex)
println(age)
println(info)
}
}
fun main() {
val p = KtBase(name = "张三", info = "学习KT语言", age = 27, sex = 'M').show()
}
5、Kotlin次构造函数
//TODO Kotlin 主构造函数与次构造函数
//一步到位,比较常用 var name:String 相当于var name = _name
class KtBase(name: String) {//主构造函数
//次构造必须调用主构造,否则报错
//为什么次构造必须调用主构造? 因为次构造很多,无法管理,必须由主构造统一管理
constructor(name: String, sex: Char) : this(name) {
println("两个参数的构造函数 name:$name,sex:$sex")
}
//三个参数的次构造函数
constructor(name: String, sex: Char, age: Int) : this(name) {
println("三个参数的构造函数 name:$name,sex:$sex,age:$age")
}
//四个参数的次构造函数
constructor(name: String, sex: Char, age: Int, info: String) : this(name) {
println("两个参数的构造函数 name:$name,sex:$sex,age:$age,info:$info")
}
}
fun main() {
val p = KtBase("李元霸")//调用主构造
KtBase("张三", 'M')//调用两个参数次构造
KtBase("张三", 'M', 27)//调用三个参数次构造
KtBase("张三", 'M', 27, "学习KT语言")//调用四个参数次构造
}
注意:次构造函数必须实现主构造函数
6、Kotlin中的默认参数
//TODO Kotlin 构造函数中的参数
//一步到位,比较常用 var name:String 相当于var name = _name
class KtBase(name: String = "李元霸") {//主构造函数
//次构造必须调用主构造,否则报错
//为什么次构造必须调用主构造? 因为次构造很多,无法管理,必须由主构造统一管理
constructor(name: String = "李连杰", sex: Char = 'M') : this(name) {
println("两个参数的构造函数 name:$name,sex:$sex")
}
//三个参数的次构造函数
constructor(name: String = "李小龙", sex: Char = 'M', age: Int = 27) : this(name) {
println("三个参数的构造函数 name:$name,sex:$sex,age:$age")
}
//四个参数的次构造函数
constructor(name: String = "李俊", sex: Char = 'W', age: Int = 26, info: String = "还在学习新的KT语言") : this(name) {
println("两个参数的构造函数 name:$name,sex:$sex,age:$age,info:$info")
}
}
fun main() {
val p = KtBase("李元霸")//调用主构造
KtBase("张三", 'M')//调用两个参数次构造
KtBase("张三", 'M', 27)//调用三个参数次构造
KtBase("张三", 'M', 27, "学习KT语言")//调用四个参数次构造
KtBase() //优先调用主构造函数
}
7、Kotlin中的初始化 init{}
//TODO Kotlin 构造函数中的参数
//一步到位,比较常用 var name:String 相当于var name = _name
class KtBase(name: String = "李元霸") {//主构造函数
//次构造必须调用主构造,否则报错
//为什么次构造必须调用主构造? 因为次构造很多,无法管理,必须由主构造统一管理
constructor(name: String = "李连杰", sex: Char = 'M') : this(name) {
println("两个参数的构造函数 name:$name,sex:$sex")
}
//三个参数的次构造函数
constructor(name: String = "李小龙", sex: Char = 'M', age: Int = 27) : this(name) {
println("三个参数的构造函数 name:$name,sex:$sex,age:$age")
}
//四个参数的次构造函数
constructor(name: String = "李俊", sex: Char = 'W', age: Int = 26, info: String = "还在学习新的KT语言") : this(name) {
println("两个参数的构造函数 name:$name,sex:$sex,age:$age,info:$info")
}
}
fun main() {
val p = KtBase("李元霸")//调用主构造
KtBase("张三", 'M')//调用两个参数次构造
KtBase("张三", 'M', 27)//调用三个参数次构造
KtBase("张三", 'M', 27, "学习KT语言")//调用四个参数次构造
KtBase() //优先调用主构造函数
}
8、Kotlin 构造函数执行顺序
//TODO Kotlin 构造函数初始化顺序
//执行顺序
//第一步生成 val sex:Char
class KtBase(_name: String, val sex: Char) {//主构造函数
//第二步 生成mName细节,由于写在init代码块前面,所以先生成,其实类成员和init是同时生成的
val mName = _name
init {
val nameValue = _name//第三步 生成nameValue细节
println("我是init代码块打印:nameValue:$nameValue")
}
constructor(name: String, sex: Char, age: Int) : this(name, sex) {
//第五步:生成次构造的细节
println("次构造函数三个参数被调用了,name:$name,sex:$sex,age:$age")
}
//第四步
var test = "AAA"
}
fun main() {
//先调用主构造,再调用init,再调用次构造
KtBase("李元霸", '男', 27)
}
9、Kotlin构造函数延迟初始化
//TODO Kotlin 构造函数延迟初始化
//执行顺序
//第一步生成 val sex:Char
class KtBase() {//主构造函数
// lateinit val AAA;// AAA无法后面修改,怎么延时初始化
lateinit var result: String //等会再初始化,所以没有赋值
//模拟服务器请求加载
fun request() {//延迟初始化,属于懒加载
result = "服务器加载成功,恭喜你"
}
fun showResponseResult() {
if (::result.isInitialized) {
println("resule:$result")
} else {
println("没有初始化加载")
}
}
}
fun main() {
val p = KtBase()
p.request()
//使用之前加载,属于懒加载
p.showResponseResult()
}
10、Kotlin 惰性初始化 byLazy
//TODO Kotlin 构造函数延迟初始化
//lateinit 是在使用时候,手动加载的懒加载方式,然后再使用
//惰性初始化 使用时候,自动加载的懒加载方式,然后再使用
class KtBase() {//主构造函数
//普通方式,不使用惰性加载 (饿汉式,没有任何懒加载特点)
// val databaseData1:String = readSQLServerDatabaseAction()
val databaseData2 by lazy { readSQLServerDatabaseAction() }
public fun readSQLServerDatabaseAction(): String {
println("加载读取数据库开始")
println("加载读取数据库数据中")
println("加载读取数据库数据中")
println("加载读取数据库数据中")
println("加载读取数据库数据中")
println("加载读取数据库数据中")
println("加载读取数据库结束")
return "数据库加载成功"
}
}
fun main() {
val p = KtBase()
Thread.sleep(5000)
println("即将开始使用")
println("最终显示:${p.databaseData2}")
}
11、Kotlin 初始化陷阱
//TODO Kotlin 初始化学习 陷阱
class KtBase(_str: String) {
//主构造函数
//陷阱一:必须写在init前面,不然不能调用,使用顺序会走到int里
var number = 9;
val info: String
val str = _str
val content: String = getInfoMethod2()
// val str = _str//陷阱三,写在方法后赋值会崩溃,必须写前面
init {
info = "OK"
getInfoMethod()
// info = "OK" //陷阱二:info写在方法后面会崩溃
number = 81
}
fun getInfoMethod() {
println("info:${info[0]}")
}
fun getInfoMethod2(): String = str
}
fun main() {
// KtBase().getInfoMethod()
println("内容的长度是:${KtBase("aaaaa").content.length}")
}