在 kotlin 中命名伴随对象有什么意义



伴随对象的文档包含以下示例

class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}

此处Factory是伴随对象的名称。然后它继续说:

可以省略伴随对象的名称,在这种情况下,将使用名称Companion

但是,我看不到使用伴随对象名称的示例。

由于每个类只能有一个伴随对象(否则会出现Only one companion object is allowed per class错误(,因此这个名称对我来说就像一些非常无用的语法糖。

伴随对象的名称实际上可以用于什么? 为什么人们会费心为它使用任何名称?

您可以使用同伴的名称,如下所示:

MyClass.create()           // not via companion name
MyClass.Companion.create() // via default companion name
MyClass.Factory.create()   // via companion name

这个名字对 Kotlin 来说可能并不那么重要,因为你可以在不知道有一个伴随对象的情况下访问该方法(上面的第一行(。它更像是一种个人风格,如果你想让对这些功能的访问更加明确。

但是对于java 互操作来说,这是有区别的,因为您必须通过配套名称访问该函数:

MyClass.Factory.create();   // with named companion
MyClass.Companion.create(); // with unnamed comanion

好吧,Kotlin 中的伴侣对象不仅仅是语法糖。它们实际上是一种类型。他们能够做更多的事情,不需要被视为静态的替代品。

您实际上可以扩展类或实现接口。请参阅下面的示例。

open class Super {
open fun sayHello() {
println("Hello")
}
}
class Some {
companion object Child : Super() {
override fun sayHello() {
super.sayHello()
println("Hello from companion object")
}
}
}
fun main() {
Some.Child.sayHello()
}

如果您不使用显式名称,则同伴名称为Companion,因此可以省略它,就像您已经引用的那样。

有时,您可能希望在调用中使用显式名称,这在您的示例中MyClass.Factory.create()。也许出于命名空间的原因。

我也看不出有很多理由来命名一个伴随对象。除非你关心 Java 与 Kotlin 代码的互操作。然后,您需要明确写入同伴姓名。

您可能关心该名称的另一个原因是,当您在其上定义扩展函数时:

fun MyClass.Companion.ext() = "myext"

在这种情况下,当它有一个像Factory这样的名称时会更清楚,通过扩展添加特定的工厂方法。

但是,我看不到使用伴随对象名称的示例。

class Person(val name: String) { companion object Loader {
fun fromJSON(jsonText: String): Person = ... }
}
>>> person = Person.Loader.fromJSON("{name: 'Dmitry'}") >>> person.name
Dmitry
>>> person2 = Person.fromJSON("{name: 'Brent'}") >>> person2.name
Brent

相关内容

  • 没有找到相关文章

最新更新