Kotlin:object关键字杂谈

作者: 泪已无痕 | 来源:发表于2018-05-28 21:11 被阅读14次

    新的项目从Java完全切换到了Kotlin,可能由于已有的思维导致大家对object这个东西有很大的困惑,这里简单介绍下个人对它的理解:

    简而言之,被object修饰的类跟普通类的唯一区别是它是单例的,并且这个单例对象是语言自动生成的,而它的应用场景,一般有以下三个方面:

    1. 单例对象
    2. 替代Java的匿名内部类
    3. 伴生对象

    对于第一点单例对象没什么好说的,唯一需要注意的一点是它不能有构造函数(不管是主构造还是从构造),因为这个单例在定义的时候就被创建了,所以构造函数也就失去了它的意义。

    对于第二点替代Java的匿名内部类,让我们先看一个例子:

    var isClicked = false
    button.setOnClickListener(object : View.OnClickListener() {
        override fun onClick(view: View?) {
           isClicked = true
        }
    }
    

    从上面的例子中可以看到它与Java匿名内部类的一些区别,我们不仅可以访问类外部的非final变量,还可以修改变量的值;另外需要注意的是,匿名对象并不是全局唯一的,每次对象表达式被执行都需要创建一个新的对象实例。

    说完了前两点,让我们把目光集中在伴生对象这个话题上,因为它常常与Java的static关键字做比较,所以需要重点讨论一下它:

    首先我们需要明确的一点是,Kotlin没有static关键字,那很多人会问我的静态属性以及静态方法怎么声明,这里有2种替代方案:

    在kotlin中,我们不仅可以导入一个类,而且还可以导入一个变量和一个函数,因此我们可以通过这种方式来替代静态属性和静态方法,比如:

    package me.tom.webaby.common.utils
    
    val REQUEST_QUERY_USER = 10
    
    fun version(): String {
        return "0.1.0"
    }
    
    package me.tom.webaby.example
    
    import me.tom.webaby.common.utils.REQUEST_QUERY_USER
    import me.tom.webaby.common.utils.version
    
    fun main(args: Array<String>) {
       println(REQUEST_QUERY_USER)
       println(version())
    }
    
    1. 通过上述方法无法满足我们的需求怎么办?比如我们经常使用的工厂方法,那么我们可以通过伴生对象来实现:
    class Student private constructor(val name: String) {
        companion object: Person(), PersonInterface {
            fun generateStudent(name: String) = Student(name)
        }
    }
    
    val student = Student.generateStudent("Tom.Huang")
    

    通过上面的例子我们可以发现,它的调用语法跟静态类完全一样,但它相对于静态类来说,它的优势是可以像其他普通类一样继承并且实现接口,这在保持我们语法习惯的同时,也给了我们很大的自由来重新组织规划我们的代码结构。

    以上是伴生对象的主要应用场景,对于它的使用我们还需要注意一点是,它的成员不能在子类中重写。

    相关文章

      网友评论

        本文标题:Kotlin:object关键字杂谈

        本文链接:https://www.haomeiwen.com/subject/kjjnjftx.html