kotlin从小白到大神Day04 2020.7.16

本文深入探讨Kotlin的高级特性,包括伴生对象、单例模式、函数扩展、函数对象及lambda表达式和高阶函数的应用。通过实例讲解,帮助读者理解并掌握这些特性在实际开发中的使用。

内容

1.伴生对象
2.kotlin中的单例模式(伴生对象应用)
3.函数扩展
4.函数对象
5.lambda表达式和高阶函数

一.伴生对象

将伴生对象理解为Java中的静态

//Java中有静态方法和实例方法
//而kotlin中的伴生对象就类似Java中的静态(虽然可能实际上并不是静态,但是可以这样理解)

//如果想定义伴生对象,就可以这样
class HttpRequest{
    companion object{
        //这里面的东西就类似于静态属性、静态方法
        var url: String = "www.baidu.com"

        fun show(){
            println("图片")
        }
    }
}

//如果某个类全是静态属性静态方法,比如工具类,那么就可以用object代替class
object ImageUti{//为工具类而生
    fun show(){

    }
}


fun main() {
    HttpRequest.url
    HttpRequest.show()

    ImageUti.show()
}

二.kotlin中的单例模式(伴生对象应用)

注意:区分饿汉式和懒汉式

//Java中饿汉式创建单例
/*
public class test01 {
    public void test(){
        test02 temp = test02.temp;
    }
}

class test02{
    public static test02 temp = new test02();
    private test02(){

    }
}

 */

//Java懒汉式
/*
public class test01 {
    public void test(){
        test02.getInstance();
    }
}

class test02{
    private static test02 instance;
    private test02(){}

    public static test02 getInstance(){
        if(instance == null){
            synchronized(test02.class){
                if(instance == null){
                    instance = new test02();
                }
            }
        }

        return instance;
    }
}

 */
//kotlin饿汉式
class Person private constructor(){//当构造方法有修饰的时候是不能省略的
    companion object{
        val person = Person()
    }
}

//kotlin懒汉式(Java模式)
class Sqlite private constructor(){
    companion object{
        var default: Sqlite? = null

        fun getInstance(): Sqlite{
            if(default == null){
                synchronized(this){
                    if(default == null){
                       default = Sqlite()
                    }
                }
                /*
                synchronized(this,{
                    if(default == null){
                        default = Sqlite()}
                })*/
            }

            return default!!//确定一定不为空
        }
    }
}

//kotlin懒汉式(kotlin模式)
class Sqlite1 private constructor(){
    companion object{
        val instance: Sqlite1 by lazy(LazyThreadSafetyMode.SYNCHRONIZED){
            Sqlite1()
        }
    }
}
fun main() {
    //Person.person
    Sqlite.getInstance()

    Sqlite1.instance
}

三.函数扩展

注意:扩展属性和扩展静态属性和方法

//在已有函数的基础上增加属性和方法有三种方式

open class car{

}
//1.让它被继承
class Audi: car(){

}


//2.装饰模式
class Dazhong{
    val car = car()

    val color: String = "黑色"

    fun show(){

    }
}
//上面两种方式都没有真正地给Car类去加属性和方法


//3.扩展  添加方法就是用 fun,添加属性就是var/val
class Student(var name: String){
    fun work(){
        println("工作")
    }

    companion object{

    }
}
//实际上并没有添加到当前这个类
fun Student.eat(){
    println("吃饭")
}
fun Student.work(){
    println("添加的work")
}//注意:当扩展方法/属性和原有的相同时,那么原有的优先级更高,也就是加不进去

//由于扩展属性没有 backing field(真正存值的变量),所以扩展属性本身不能存值,也不能初始化,它只是一个入口
//相当于只是在类里面添加了对应的set或者get方法
//所以必须为扩展属性显式声明set/get(val无set)
val Student.grade: Int
    get(){
       println("正在计算grade")//模拟计算过程
        return 1
    }
var Student.score: Float
    get() = 85.5f
    set(value) {
        println("${name}_${value}")
    }
//扩展静态属性和方法(首先类里面要有伴生对象)
fun Student.Companion.show(){
    println("扩展的静态方法")
}
val Student.Companion.url: String
    get() = "www.baidu.com"
fun main() {
    var s: Student = Student("小王")
    s.work()//输出 工作
    s.eat()//输出 吃饭

    s.score = 89.9f//输出 小王_89.9

    //访问扩展的静态方法和属性(注意这里要用Student去点出来而不是s)
    Student.show()//输出 扩展的静态方法
    Student.url.also {
        println(it)//输出 www.baidu.com
    }

}

四.函数对象

注意函数表示方法以及invoke方法

//有多个函数,里面不知道执行哪一个,这时候可以由外部来确定
fun loadHomeData(id: Int): String{
    println("加载主页数据")
    return "加载成功。。。数据"
}

fun saveUserInfo(id: Int):String{
    println("保存信息")
    return "保存信息成功"
}

fun main(){
    //函数名仅仅就是这个函数的名称,函数名前面加 :: 才表示这个函数的对象
    var funA = ::loadHomeData
    var funB = ::saveUserInfo
    var funC = fun(id: Int): String{
      println("加载主页数据")
      return "加载成功。。。数据"
    }//只能是匿名函数

    //可以通过定义的变量来调用函数
    funA(10).also { println(it) }
    funB(20).also { println(it) }

    //可以通过函数对象来调用函数(上面的变量也是函数对象)
    //只不过注意要加括号
    (::loadHomeData)(10).also { println(it) }
    (::loadHomeData).invoke(10).also { println(it) }
}
/*
加载主页数据
加载成功。。。数据
保存信息
保存信息成功
加载主页数据
加载成功。。。数据
加载主页数据
加载成功。。。数据
 */

五.lambda表达式和高阶函数(重点)

注意:函数类型的表示方法以及高阶函数写法

//有多个函数,里面不知道执行哪一个,这时候可以由外部来确定
fun loadHomeData(id: Int): String{
    println("加载主页数据")
    return "加载成功。。。数据"
}

fun saveUserInfo(id: Int):String{
    println("保存信息")
    return "保存信息成功"
}
fun login(name: String,funParam:(Int) -> String){
    //登录
    val id = 1

    //进一步操作
    funParam(1).also { println(it) }
}
fun main(){
    //不太纯的匿名函数
    var funA = fun(id: Int): String{
        println("加载主页数据")
        return "加载成功。。。数据"
    }

    //lambda表达式就是匿名函数,而且是纯的匿名函数
    //注意:如果函数有返回值,则不能使用return,默认返回最后一行的内容
    //形式:
    //函数使用大括号括起来{
    //   函数的参数 -> 返回值类型
    //   函数体body
    //}
    //下面是 (Int) -> String 类型的函数
    var funB = { id: Int -> String
        println("加载主页数据")
        "$id 加载成功。。。数据"
    }
    //下面是 (Int,Int) -> Int 类型的函数
    var funC = { a: Int,b: Int -> Int
        a + b
    }

    login("jack",funB)
    /*
    加载主页数据
    1 加载成功。。。数据

     */

    //因为变量只用了一次,所以可以直接将函数作为参数传递过来
    login("jack",{ id: Int -> String
        println("加载主页数据")
        "$id 加载成功。。。数据"
    })

    //如果某参数为函数,并且是最后一个参数,那么可以这样写
    login("jack"){id: Int -> String
        println("加载主页数据")
        "$id 加载成功。。。数据"
    }

    //最精简的
    //如果lambda表达式中参数只有一个,那么这个参数可以省略
    //高阶函数
    login("jack"){
        println("加载主页数据")
        "$it 加载成功。。。数据"
    }
    //还原:fun login(name: String,funParam: (id:Int) -> String)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值