Kotlin笔记(4)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GXH_APOLOGIZE/article/details/80681125
中缀表达式
  • 使用中缀表达式就是想让代码更加简洁易懂
  • 使用条件:必须是成员函数或扩展函数;必须只有一个参数;参数不可能是可变参数或默认参数。
class Person{
    infix fun sayHelloTo(name:String){
        println("你好${name}")
    }
}


val stenve=Person()
stenve.sayHelloTo("百里屠苏")
//中缀表达式就是想让代码更加简洁易懂
//加infix后就可以下面这么写
stenve sayHelloTo "百里屠苏"

//自定义操作符、区间、元组
val pair=Pair<String,Int>("百里屠苏",25)
val pair2="百里屠苏" to 25
委托
//这里我们举例小头爸爸把洗碗委托给大头儿子
interface WashPower{
    fun wash()
}

class BigHeadSon:WashPower{
    override fun wash() {
        println("大头儿子洗碗")
    }
}

//方式一
//class SmallHeadFather:WashPower by BigHeadSon()
//方式二
class SmallHeadFather(var washPower: WashPower):WashPower by washPower


//--------------------使用
//方式一
//    val father=SmallHeadFather()
//    father.wash()

//方式二
val bigSon=BigHeadSon()
val smallFather=SmallHeadFather(bigSon)
smallFather.wash()

//类委托加强
class SmallHeadFather(var washPower: WashPower):WashPower by washPower{
    override fun wash() {
        println("添加一些操作...")
        //小头儿子洗碗
        washPower.wash()
        println("添加一些操作...")
    }
}

//属性委托:把当前类字段的get、set方法委托给其它类。
class BigHeadSon:WashPower{
    var money:Int by Monther()
    override fun wash() {
        println("大头儿子洗碗")
    }
}

class Monther{
    operator fun getValue(bigHeadSon: BigHeadSon, property: KProperty<*>): Int {
        return sonMoney
    }

    operator fun setValue(bigHeadSon: BigHeadSon, property: KProperty<*>, i: Int) {
        sonMoney+=i
    }
    var sonMoney=0
    var meMoney=0
}
惰性加载 by lazy

如果一个字段是固定值,我们一般用val,比如val name:String=”haha”,但是这种写法,如果多了,会占内存。这时候可以用by lazy,当使用的时候才会初始化。

惰性加载注意:

  • 必须val修饰字段
  • by lazy可以放在成员变量中,也可以单独存在
  • by lazy返回值就是最后一行
  • by lazy是线程安全的
class Person{
    val name:String="haha"
    val color:String by lazy { "black" }
}
延迟加载

类的字段要么初始化,要么abstract,不然编译不过,但是我可能使用的时候才知道赋什么值,如果现在随便赋值比如var name:String=”“,后面忘记赋值的话问题就可能不在掌握之中了…..
这时候可以使用延迟加载lateinit,使用这个关键字可以不初始化赋值,在使用的时候你没赋值的话会报异常kotlin.UninitializedPropertyAccessException

class Person{
    lateinit var name:String
}
by lazy和lateinit比较
  • 都可以放在成员变量或者单独使用
  • by lazy知道具体值,用的时候加载
  • lateinit不知道具体值,用的时候才赋值
  • by lazy用val修饰变量,lateinit用var修饰变量
扩展函数

不改变已有类的情况下,为类添加新的函数,扩展函数主要是替代java的util类。子类可以调用父类的扩展函数,但是不能重写。

//格式:类.函数名:返回值
fun String?.isStrEmpty():Boolean{
    return this==null||this.length==0
}

val str:String?=null
val isEmpty=str.isStrEmpty()
println(isEmpty)
单例

object单例:Kotlin提供了object单例,所有的字段都是static,方法不是。
所以,object单例有个问题就是如果字段太多,还是有点消耗内存的。所以object单例适用于字段不多的时候。

object Utils{
    var name="haha"
    fun sayHello(){
        println("hello")
    }
}

println(Utils.name)
Utils.sayHello()

java中可以控制字段是静态的还是非静态的,Kotlin中没有static关键字。那么怎么控制字段静态和非静态呢?伴生对象。

class Ceshi{
    var age=20
    companion object {
        //静态的字段
        var name="hehe"
    }
}

我们都知道java中的单例,可以控制只有一个实例,也可以控制字段的静态非静态,那么Kotlin怎么实现像java一样的单例呢?

class Utils private constructor(){
    var age=20
    companion object {
        var name="ahah"
        val instance by lazy { Utils() }
    }
}
枚举
enum class WEEK{
    Mon,Tues,Wed,Thur,Fri,Sat,Sun
}
enum class COLOR(var r:Int,var g:Int,var b:Int){
    RED(255,0,0),BLUE(0,0,255),GREEN(0,255,0)
}


println(WEEK.Fri)
val result=WEEK.values()
result.forEach { println(it) }
println(COLOR.GREEN.b)
数据类

class前加data,会默认生成构造函数、get、set、equals、hashCode、toString等。

//数据类
data class News(var title:String,var des:String){

}

//-----------------使用
val news=News("标题","简介")
println(news.title)
println(news.des)

news.component1()//第一个元素
news.component2()//第二个元素

//解构
val (title,des)=News("标题","描述")
println(title)

猜你喜欢

转载自blog.csdn.net/GXH_APOLOGIZE/article/details/80681125