Какой смысл называть объект-компаньон в 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