kotlin--Object关键字

1.匿名内部类
Object可以实现,继承一个抽象类的同时,实现多个接口。

复制代码
interface A {
    fun funA()
}


interface B {
    fun funB()
}


abstract class Man {
    abstract fun findMan()
}


fun main() {
    // 这个匿名内部类,在继承了Man类的同时,还实现了A、B两个接口
    val item = object : Man(), A, B{
        override fun funA() {
            // do something
        }
        override fun funB() {
            // do something
        }
        override fun findMan() {
            // do something
        }
    }
}

2.实现单例模式

复制代码
object UserManager {
    fun login() {}
}

3.伴生对象,实现静态方法访问的效果

复制代码
class Person {
//  改动在这里
//     ↓
    companion object InnerSingleton {
        @JvmStatic
        fun foo() {}
    }
}


实现工厂模式:
User.create("Tome")
//  私有的构造函数,外部无法调用
//            ↓
class User private constructor(name: String) {
    companion object {
        @JvmStatic
        fun create(name: String): User? {
            // 统一检查,比如敏感词过滤
            return User(name)
        }
    }
}

4.Object实现单例模式

复制代码
object UserManager {
    // 对外暴露的 user
    val user by lazy { loadUser() }


    private fun loadUser(): User {
        // 从网络或者数据库加载数据
        return User.create("tom")
    }


    fun login() {}
}
UserManager.user
只有访问的时候才加载用户

======================================================================

伴生对象Double check
class UserManager private constructor(name: String) {
    companion object {
        @Volatile private var INSTANCE: UserManager? = null


        fun getInstance(name: String): UserManager =
            // 第一次判空
            INSTANCE?: synchronized(this) {
            // 第二次判空
                INSTANCE?:UserManager(name).also { INSTANCE = it }
            }
    }
}


// 使用
UserManager.getInstance("Tom")

第一次判空,没有进入同步资源,避免同步开销;
第二次判空,进入同步块,确保只有一个线程去创建该对象。第二次判空的原因是,
有可能存在其他线程创建了该对象。
===================================================================================================

抽象类模板