小白笔记(持续更新中)
get/set函数的使用与field关键字的使用
//var(可读可写)修饰的变量默认存在get set函数
//get set 如果不做修改可以不用写 默认存在的
//get set函数放在谁的下面就是谁的函数
class Test01 {
var name="李白见"
//field关键字 我的理解: field == this.name
get() = field
set(value) {
field=value
}
var num=89
//field关键字 我的理解: field == this.num
get() = field
set(value) {
field=value
}
}
fun main() {
//test一个实例对象
val test=Test01()
test.name="李渐渐"
test.num=78
println(test.num)
println(test.name)
//每次Test01()代表重新new了一个实例对象,它的属性值为之前默认的
println(Test01().num)
println(Test01().name)
}
计算属性 与 防范竞态条件
class Test02 {
//val 只读 只存在get函数
val infoNumber:Int
//计算属性 通过覆盖get/set来定义的属性,不需要field了 声明属性时不能被赋值
get()=(1..1000).shuffled().first() //从1-1000取随机数, 返回给getInfoNumber()函数
//防范竞态条件 当你调用成员,这个成员,可能为null,可能为空值(""),就必须采用 防范竞态条件, 这个是KT编程的规范化
var information:String? ="" //null / ""
fun showInformation():String?{
//这种写法就属于 防范竞态条件 (专业写法)
return information?.let {
if(it.isBlank()){
"原来你是Null"
}else{
"最终的结果是$it"
}
} ?: "原来你是Null"
}
}
fun main() {
println(Test02().infoNumber)
println(Test02().showInformation())
}
主构造函数
//主构造函数: 规范来说,都是以_xxx的形式命名的,临时的输入类型,不能直接用,需要通过声明接收下来,成为变量才能用
class Test03(_name:String,_sex:Char,_age:Int,_info:String) //主构造函数
{
var sex=_sex
get() = field
var age=_age+10
get() = field
var info=_info
get() = field
var name=_name
get() = field //get函数不允许私有化
private set(value) {field=value}
fun show(){
println(name) // name==this.getName()
println(sex)
println(info)
println(age)
}
}
//主构造函数
fun main() {
val test03 = Test03("李渐渐", '女', 10, "信息")
//test03.name="李防范" set被私有化了,不能调用
test03.show()
}
主构造函数里定义属性
class Test04(var name:String,var sex:Char,val age:Int,val info:String){//主构造函数
fun show(){
println(name) // name==this.getName()
println(sex)
println(info)
println(age)
}
}
fun main() {
val test04 = Test04("李渐渐", '男', 10, "信息")
test04.show()
}
次构造函数constructor(参数):主构造函数{}
使用次构造函数时,先调用主构造函数,然后执行{}内的内容
class Test05 (name:String ) {
//次构造函数必须调用主构造函数,否则报错
//必须调用主构造函数的原因:主构造统一管理,为了更好的初始化
constructor(name: String,info:String):this(name){
println("$info")
}
constructor(name: String,sex:Char,info:String):this(name){
println("${info}和$sex")
}
constructor(name: String,sex:Char,info:String,age:Int):this(name){
println("${info}和${sex}和${age}和${name}")
}
}
fun main() {
Test05("名字", '男', "信息",88)
}
构造函数中的默认参数
class Test06 (name: String?="李小龙") {
constructor(name: String?="李小龙",info:String?="信息"):this(name){
println("${info}和${name}")
}
constructor(name: String?="李小龙",sex:Char='男',info:String="信息"):this(name){
println("${info}和$sex")
}
constructor(name: String?="李小龙",sex:Char='男',info:String="信息",age:Int=82):this(name){
println("${info}和${sex}和${age}和${name}")
}
}
fun main() {
//public constructor Test06( name: String = "李小龙" )
Test06() //优先调用主构造函数
Test06(null,null) //运行结果: null和null
Test06(age=56) //运行结果: 信息和男和56和李小龙
}
init{} 主构造函数的代码块
// name/age/sex 临时变量可以在构造函数代码块中使用 但不能在方法中使用,要想使用,必须先进行二次接收
class Test07(name:String,age:Int,sex:Char){
// init 主构造函数的代码块
init {
println("主构造函数被调用了: $age")
//require 验证是否符合规范 不符合的抛出异常并输出
require(age>0){ "年龄输入不对" }
}
constructor(name:String):this("王五",55,'男'){
println("次构造函数被调用了: $name")
}
}
fun main() {
Test07("李四",88,'女')
Test07("二狗")
}
require(age>0){ “年龄输入不对” } , age为-1时的运行结果:
构造函数初始化顺序
class Test08 (_age:Int,val sex:Char){
// this.sex = sex;
// this.derry = "AAA";
// this.age = _age;
// int ageText = this.age;
// String var4 = "主构造函数被调用了: " + ageText;
// System.out.println(var4);
// this.text = "CVV";
// 先声明sex参数(主构造函数中直接声明的参数) 其他的按代码顺序继续向下执行
val derry="AAA"
val age=_age
init {
val ageText=age
println("主构造函数被调用了: $ageText")
}
constructor(name:String, age:Int, sex:Char):this(55,'男'){
println("次构造函数被调用了: $name")
}
val text="CVV"
}
fun main() {
Test08(50,'男')
Test08("王五",78,'女')
}
lateinit var 变量名:变量类型 延迟初始化
// ::变量名.isInitialized 判断变量是否初始化
class Test09 {
lateinit var response:String
fun loadRequest(){
response="登录成功!"
}
fun showResult(){
if(::response.isInitialized){
println(response)
}else{
println("您还没有输入账号或密码")
}
}
}
fun main() {
val test=Test09()
test.loadRequest()
test.showResult()
}
惰性初始化 by lazy
class Test10 {
//普通方式(饿汉式 没有任何懒加载的特点)
// val database=readSqlAction()
//惰性初始化by lazy 使用的时候,自动加载的懒加载方式
val database by lazy { readSqlAction() }
private fun readSqlAction():String{
println("开始读取")
println("读取中")
println("结束读取")
return "database read"
}
}
fun main() {
val test=Test10()
Thread.sleep(5000)
println("即将开始读取")
println("结果:${test.database}")
}