对象声明
单例是一种面向对象模式,其中一个类只能有一个实例(对象)。
例如,您正在处理一个具有 SQL 数据库后端的应用程序。您想创建一个连接池来访问数据库,同时为所有客户端重用相同的连接。为此,您可以通过单例类创建连接,以便每个客户端获得相同的连接。
Kotlin 使用对象声明功能提供了一种创建单例的简单方法。为此,使用了 `object` 关键字。
object SingletonExample { ... .. ... // body of class ... .. ... }
上面的代码结合了一个类声明和一个该类的单个实例 `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("Eating food.")
fun talk() = println("Talking with people.")
open fun pray() = println("Praying god.")
}
fun main(args: Array<String>) {
val atheist = object : Person() {
override fun pray() = println("I don't pray. I am an atheist.")
}
atheist.eat()
atheist.talk()
atheist.pray()
}
运行程序后,输出将是
Eating food. Talking with people. I don't pray. I am an atheist.
在此,匿名对象存储在变量 `atheist` 中,该变量实现了 `Person` 类,并重写了 `pray()` 方法。
如果您正在实现一个具有构造函数的类来声明匿名对象,您需要传递适当的构造函数参数。例如,
open class Person(name: String, age: Int) {
init {
println("name: $name, age: $age")
}
fun eat() = println("Eating food.")
fun talk() = println("Talking with people.")
open fun pray() = println("Praying god.")
}
fun main(args: Array<String>) {
val atheist = object : Person("Jack", 29) {
override fun pray() = println("I don't pray. I am an atheist.")
}
atheist.eat()
atheist.talk()
atheist.pray()
}
运行程序后,输出将是
name: Jack, age: 29 Eating food. Talking with people. I don't pray. I am an atheist.