Какой смысл называть объект-компаньон в kotlin

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

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

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

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

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

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

Для чего на самом деле может использоваться имя объекта-компаньона? Зачем кому-то использовать это имя?

3 ответа

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

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
Другие вопросы по тегам