Kotlin 伴生对象
最后修改于 2025 年 4 月 19 日
Kotlin 的伴生对象提供了一种定义类级别属性和方法的方式,类似于 Java 的静态成员。companion 关键字声明属于类而不是实例的这些成员。本教程通过实际例子深入探讨了伴生对象。
基本定义
伴生对象使用 companion 关键字在类中声明。它可以包含可以在不创建类实例的情况下调用的属性和方法。伴生对象在加载包含类时被初始化。
基本伴生对象
最简单的伴生对象形式提供了类级别的功能。成员可以直接使用类名访问,类似于 Java 中的静态成员。
package com.zetcode
class MyClass {
companion object {
fun create(): MyClass = MyClass()
val PI = 3.1415
}
}
fun main() {
val instance = MyClass.create()
println(MyClass.PI) // Output: 3.1415
}
在这里,我们定义了一个伴生对象,其中包含一个工厂方法 create 和一个常量 PI。两者都通过类名访问,无需创建实例。这演示了基本伴生对象的使用。
带名称的伴生对象
伴生对象可以有名称,这在实现接口或扩展类时很有用。名称出现在 companion 关键字之后。
package com.zetcode
interface Factory<T> {
fun create(): T
}
class MyClass {
companion object Named : Factory<MyClass> {
override fun create(): MyClass = MyClass()
fun hello() = println("Hello from companion")
}
}
fun main() {
val instance = MyClass.create()
MyClass.hello() // Output: Hello from companion
}
此示例显示了一个实现 Factory 接口的带名称的伴生对象。名称 Named 允许我们在需要时显式引用伴生对象类型,同时仍然提供类级别的访问。
伴生对象属性
伴生对象可以保存类级别的属性,这些属性维护状态。这些属性在加载类时被初始化,并在所有实例之间共享。
package com.zetcode
class Counter {
companion object {
private var count = 0
fun increment() = ++count
fun currentCount() = count
}
}
fun main() {
Counter.increment()
Counter.increment()
println(Counter.currentCount()) // Output: 2
}
Counter 类使用伴生对象在所有实例中维护一个计数。count 属性对伴生对象是私有的,显示了伴生对象如何封装类级别的状态。
伴生对象作为工厂
伴生对象通常用于实现工厂模式,提供创建实例的替代方法,同时隐藏构造函数细节。
package com.zetcode
class User private constructor(val name: String) {
companion object {
fun create(name: String): User {
return User(name.trim())
}
fun createAdmin(): User {
return User("Admin")
}
}
}
fun main() {
val user = User.create(" John ")
val admin = User.createAdmin()
println(user.name) // Output: John
println(admin.name) // Output: Admin
}
在这里,User 构造函数是私有的,强制通过伴生对象的工厂方法创建。这允许预处理(例如修剪)并提供命名的构造函数(createAdmin)以提高可读性。
伴生对象扩展
扩展函数可以添加到伴生对象中,从而提供可以在类名上调用的附加功能。
package com.zetcode
class MyClass {
companion object
}
fun MyClass.Companion.hello() = println("Hello from extension")
fun main() {
MyClass.hello() // Output: Hello from extension
}
此示例向 MyClass 的伴生对象添加了一个扩展函数。该函数直接在类名上调用。注意当伴生对象未命名时的 Companion 默认名称。
带有常量的伴生对象
伴生对象是定义与类相关的常量的理想选择,提供了比顶级常量更好的组织方式。
package com.zetcode
class Color {
companion object {
const val RED = "#FF0000"
const val GREEN = "#00FF00"
const val BLUE = "#0000FF"
fun allColors() = listOf(RED, GREEN, BLUE)
}
}
fun main() {
println(Color.RED) // Output: #FF0000
println(Color.allColors()) // Output: [#FF0000, #00FF00, #0000FF]
}
Color 类在其伴生对象中将相关的颜色常量分组在一起。const val 使这些成为编译时常量。伴生对象还提供了实用方法,例如 allColors。
用于接口实现的伴生对象
伴生对象可以实现接口,允许类在类级别提供接口功能,而无需创建实例。
package com.zetcode
interface Logger {
fun log(message: String)
}
class MyClass {
companion object : Logger {
override fun log(message: String) {
println("LOG: $message")
}
}
}
fun main() {
MyClass.log("Test message") // Output: LOG: Test message
}
在这里,伴生对象实现了 Logger 接口,允许直接在类名上调用日志记录功能。这种模式对于不需要实例状态的实用功能很有用。
伴生对象的最佳实践
- 用于类级别成员:将属于类而不是实例的属性和方法放在伴生对象中。
- 考虑命名:在实现接口或需要显式类型时,为伴生对象命名。
- 工厂模式:使用伴生对象来实现工厂方法并控制对象创建。
- 常量组织:将相关的常量分组在伴生对象中以更好地组织代码。
- 扩展函数:将扩展函数添加到伴生对象以增强类的功能。
来源
本教程深入介绍了 Kotlin 的 companion 关键字,展示了如何创建和使用伴生对象用于各种目的。我们探讨了工厂模式、常量、接口实现和扩展。伴生对象提供了一种强大的方式来组织 Kotlin 中的类级别功能。
作者
列出 所有 Kotlin 教程。