companion objects的文档包含以下示例
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
此处Factory
是随播广告对象的名称。然后继续说:
可以省略伴随对象的名称,在这种情况下将使用名称
Companion
:
但是,我没有看到使用伴随对象名称的示例。
由于每个类只能有一个伴随对象(否则会出现Only one companion object is allowed per class
错误),这个名字对我来说就像是一些非常无用的语法糖。
伴侣对象的名称实际上可以用于什么? 为什么要为它使用任何名称呢?
答案 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