新的项目从Java完全切换到了Kotlin,可能由于已有的思维导致大家对object这个东西有很大的困惑,这里简单介绍下个人对它的理解:
简而言之,被object修饰的类跟普通类的唯一区别是它是单例的,并且这个单例对象是语言自动生成的,而它的应用场景,一般有以下三个方面:
- 单例对象
- 替代Java的匿名内部类
- 伴生对象
对于第一点单例对象
没什么好说的,唯一需要注意的一点是它不能有构造函数(不管是主构造还是从构造),因为这个单例在定义的时候就被创建了,所以构造函数也就失去了它的意义。
对于第二点替代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())
}
- 通过上述方法无法满足我们的需求怎么办?比如我们经常使用的工厂方法,那么我们可以通过
伴生对象
来实现:
class Student private constructor(val name: String) {
companion object: Person(), PersonInterface {
fun generateStudent(name: String) = Student(name)
}
}
val student = Student.generateStudent("Tom.Huang")
通过上面的例子我们可以发现,它的调用语法跟静态类完全一样,但它相对于静态类来说,它的优势是可以像其他普通类一样继承并且实现接口,这在保持我们语法习惯的同时,也给了我们很大的自由来重新组织规划我们的代码结构。
以上是伴生对象
的主要应用场景,对于它的使用我们还需要注意一点是,它的成员不能在子类中重写。
网友评论