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