对象
object
关键字定义了类似类的东西。然而,您不能创建object
的实例,它只有一个实例。这有时被称为单例模式。
object
是将逻辑上属于一起的函数和属性组合在一起的一种方式,但此组合不需要多个实例,或者您想明确阻止多个实例。您永远不会创建 object
的实例,因为只有一个实例,并且在定义 object
后可以使用它:
// Objects/ObjectKeyword.kt
package objects
import atomictest.eq
object JustOne {
val n = 2
fun f() = n * 10
fun g() = this.n * 20 // [1]
}
fun main() {
// val x = JustOne() // Error
JustOne.n eq 2
JustOne.f() eq 20
JustOne.g() eq 40
}
在这里,您不能使用 JustOne()
来创建类 JustOne
的新实例。这是因为 object
关键字定义了结构并同时创建了对象。此外,它将元素放置在 object
的命名空间内。如果您只想让 object
在当前文件中可见,您可以将其设置为 private
。
- [1] 关键字
this
指的是单个对象实例。
您不能为 object
提供参数列表。
在使用 object
时,命名约定略有不同。通常情况下,当我们创建一个类的实例时,我们会将实例名称的第一个字母小写。然而,在创建 object
时,Kotlin 定义类并同时创建该类的单个实例。因此,我们将 object
的名称的第一个字母大写,因为它还表示一个类。
object
可以继承普通类或接口:
// Objects/ObjectInheritance.kt
package objects
import atomictest.eq
open class Paint(val color: String) {
open fun apply() = "Applying $color"
}
object Acrylic: Paint("Blue") {
override fun apply() =
"Acrylic, ${super.apply()}"
}
interface PaintPreparation {
fun prepare(): String
}
object Prepare: PaintPreparation {
override fun prepare() = "Scrape"
}
fun main() {
Prepare.prepare() eq "Scrape"
Paint("Green").apply() eq "Applying Green"
Acrylic.apply() eq "Acrylic, Applying Blue"
}
只有一个 object
实例,因此该实例在使用它的所有代码之间共享。这里是一个位于自己的 package
中的 object
:
// Objects/GlobalSharing.kt
package objectsharing
object Shared {
var i: Int = 0
}
现在,我们可以在不同的包中使用 Shared
:
// Objects/Share1.kt
package objectshare1
import objectsharing.Shared
fun f() {
Shared.i += 5
}
还可以在第三个包中使用:
// Objects/Share2.kt
package objectshare2
import objectsharing.Shared
import objectshare1.f
import atomictest.eq
fun g() {
Shared.i += 7
}
fun main() {
f()
g()
Shared.i eq 12
}
您可以从结果中看到 Shared
在所有包中都是相同的对象,这是因为 object
创建一个单一的实例。如果将 Shared
设置为 private
,它在其他文件中将不可用。
object
不能放在函数内部,但它们可以嵌套在其他 object
或类内部(前提是这些类本身不是在其他类内部嵌套的):
// Objects/ObjectNesting.kt
package objects
import atomictest.eq
object Outer {
object Nested {
val a = "Outer.Nested.a"
}
}
class HasObject {
object Nested {
val a = "HasObject.Nested.a"
}
}
fun main() {
Outer.Nested.a eq "Outer.Nested.a"
HasObject.Nested.a eq "HasObject.Nested.a"
}
还有一种将 object
放在类内部的方法:companion object
,您将在 伴生对象 部分中看到。
练习和解决方案可以在 www.AtomicKotlin.com 上找到。