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

时间:2017-08-24 05:18:21

标签: kotlin kotlin-companion

companion objects的文档包含以下示例

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

此处Factory是随播广告对象的名称。然后继续说:

  

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

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

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

伴侣对象的名称实际上可以用于什么? 为什么要为它使用任何名称呢?

4 个答案:

答案 0 :(得分:8)

您可以使用随播广告的名称:

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

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

但对于 java interop ,它会有所不同,因为你必须通过配套名称访问该功能:

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

答案 1 :(得分:2)

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

有时您可能希望在通话中使用明确的名称,例如MyClass.Factory.create()。出于命名空间的原因,也许。

我也没有看到命名伴侣对象的原因很多。除非您关心使用Kotlin代码的Java互操作。然后,您需要显式写入随播广告名称。

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

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

在这种情况下,当它具有类似Factory的名称时,可以更清楚,通过扩展名添加特定的工厂方法。

答案 2 :(得分:2)

好吧,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()
}

答案 3 :(得分:0)

  

然而,我没有看到使用伴侣对象名称的例子。

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
相关问题