Kotlin 对象声明和表达式
提示
- 对象声明:Kotlin 使用
object
关键字声明单例类,创建的对象是全局唯一的。这种方式适合在程序中需要一个共享资源或单例模式的场合。 - 对象表达式:使用
object
关键字还可以创建匿名类的对象(匿名对象),用于扩展现有类或实现接口,而无需显式声明新的子类。 - 应用场景:对象声明适用于单例模式,而对 象表达式适合在需要类的简单修改或临时实现时使用,如创建监听器或各种适配器。
对象声明
单例是一种面向对象的模式,其中一个类只能有一个实例(对象)。
例如,你正在开发一个具有 SQL 数据库后端的应用程序。你想创建一个连接池来访问数据库,同时为所有客户端重用同一个连接。为此,你可以通过单例类创建连接,以便每个客户端获得相同的连接。
Kotlin 使用对象声明特性提供了一种简单的方式来创建单例。为此,使用 object
关键字。
object SingletonExample {
... .. ...
// 类的主体
... .. ...
}
上述代码结合了一个类声明和该类的单个实例 SingletonExample
的声明。
对象声明可以包含属性、方法等。然而,它们不允许拥有构造器(这是有意义的)。为什么?
类似于普通类的对象,你可以使用 .
符号调用方法和访问属性。
示例:对象声明
object Test {
private var a: Int = 0
var b: Int = 1
fun makeMe12(): Int {
a = 12
return a
}
}
fun main(args: Array<String>) {
val result: Int
result = Test.makeMe12()
println("b = ${Test.b}")
println("result = $result")
}
当你运行程序时,输出将是:
b = 1
result = 12
对象声明可以像普通类一样继承自类和接口。
单例和依赖注入
对象声明有时可能很有用。然而,在与系统的许多其他部分交互的大型软件系统中,它们并不理想。
推荐阅读:依赖注入 & 单例设计模式
Kotlin 对象表达式
object
关键字也可以用来创建匿名类的对象,称为匿名对象。如果你 需要为某个类或接口创建一个稍作修改的对象,而不声明它的子类,就会使用它们。例如,
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
})
(该示例取自官方 Kotlin 文档页面。)
这里,声明了一个扩展 MouseAdapter
类的匿名对象。程序重写了两个 MouseAdapter
方法:mouseClicked()
和 mouseEntered()
。
如果需要,您可以为匿名对象指定一个名称,并将其存储在变量中。例如,
val obj = object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) {
// ...
}
override fun mouseEntered(e: MouseEvent) {
// ...
}
}
示例:Kotlin 对象表达式
open class Person() {
fun eat() = println("吃食物。")
fun talk() = println("与人交谈。")
open fun pray() = println("祈祷上帝。")
}
fun main(args: Array<String>) {
val atheist = object : Person() {
override fun pray() = println("我不祈祷。我是无神论者。")
}
atheist.eat()
atheist.talk()
atheist.pray()
}
当你运行程序时,输出将是:
吃食物。
与人交谈。
我不祈祷。我是无神论者。
在这里,匿名对象被存储在变量 atheist
中,它实现了 Person
类,并重写了 pray()
方法。
如果您要实现一个具有构造函数的类来声明匿名对象,则需要传递适当的构造函数参数。例如,
open class Person(name: String, age: Int) {
init {
println("姓名:$name,年龄:$age")
}
fun eat() = println("吃食物。")
fun talk() = println("与人交谈。")
open fun pray() = println("祈祷上帝。")
}
fun main(args: Array<String>) {
val atheist = object : Person("Jack", 29) {
override fun pray() = println("我不祈祷。我是无神论者。")
}
atheist.eat()
atheist.talk()
atheist.pray()
}
当你运行程序时,输出将是:
姓名:Jack,年龄:29
吃食物。
与人交谈。
我不祈祷。我是无神论者。