Какова точка назначения сопутствующего объекта в котлин

Документация для сопутствующих объектов имеет следующий пример

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

Здесь Factory - имя сопутствующего объекта. Затем он продолжает:

Имя сопутствующего объекта может быть опущено, и в этом случае будет использоваться имя Companion:

Однако нет примера, который я вижу, который использует имя сопутствующего объекта.

Так как у вас может быть только один сопутствующий объект для каждого класса (в противном случае вы получите ошибку Only one companion object is allowed per class), то это имя похоже на довольно бесполезный синтаксический сахар для меня.

Как можно использовать имя сопутствующего объекта? Почему бы вам не использовать какое-либо имя для этого?

Ответ 1

Вы можете использовать имя компаньона, например:

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

Ответ 2

Если вы не используете явное имя, имя компаньона Companion, поэтому его можно опустить, как вы уже цитировали.

Иногда вы можете захотеть иметь явное имя в своих вызовах, которое в вашем примере будет MyClass.Factory.create(). Возможно, для пространства имен.

Я не вижу много причин , чтобы назвать объект-компаньон. Кроме того, если вам интересно, что Java взаимодействует с вашим кодом Kotlin. Затем вам нужно явно написать имя компаньона.

Еще одна причина, по которой вам может быть интересно имя, заключается в определении функции расширения на ней:

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

В этом случае он может быть более четким, если у него есть имя типа Factory, на котором определенные методы factory добавляются через расширение.

Ответ 3

Однако нет примера, что я вижу, что использует имя сопутствующего объекта.

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