Intereting Posts
rxjava2 – простой пример выполнения задач в пуле потоков, подписывается на один поток Kotlin: Как я могу получить класс делегирования свойства члена? Контекст не может быть предоставлен без @ Provides- или @ Produces-аннотированного метода в kotlin Делегация класса Колтина, передавая это делегату построение графа для кода kotlin Kotlin – MainActivity расширяет AppCompatActivity, функция onRequestPermissionsResult не найдена и не может быть переопределена Почему код в выражении объекта может обращаться к переменным из области, содержащей его в kotlin? Можно ли запустить AsyncWebRequest через браузер? Как можно присвоить значение присваивания _id в Котлин? Mockito Wanted, но не вызывается Разница между нитью и сопрограммой в Котлине Как я могу получить имя свойства Kotlin? В Kotlin, как мне добавить методы расширения в другой класс, но только видимый в определенном контексте? Как десериализовать Firestore DocumentSnapshot, содержащий DocumentReference, используя Kotlin Как инициализировать List <T> в Котлине?

Компонентные объекты обеспечивают возможность реализации интерфейсов

Почему в объектах компаньона Kotlin / Scala могут быть реализованы некоторые интерфейсы, какие преимущества это может иметь? Когда полезно использовать эту функцию?

    Поскольку companion object s является object s, object s может реализовывать интерфейсы (или расширять классы), и нет веских причин запретить его для companion object s в частности.

    Одно распространенное использование в Scala для фабрик: например, Seq , List , Vector и т. Д. Сопутствующие объекты расширяют TraversableFactory поэтому вы можете писать код, работающий с TraversableFactory и передавать любой из них для построения типа, который вы хотите. Например

     def build[CC[X] <: Traversable[X] with GenericTraversableTemplate[X, CC], A](factory: TraversableFactory[CC])(elems: A*) = factory(elems) // build(List)(1,2,3) == List(1, 2, 3) // build(Set)(1,2,3) == Set(1, 2, 3) 

    Аналогично, все сопутствующие объекты класса класса расширяют типы функций.

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

    Например, Scala's Nil реализует List[Nothing] . Вместо каждого типа списка для реализации конкретного Nil есть только один из них.

    В шаблоне typeclass , где у вас есть только один implicit object для соответствующей реализации.

    Кроме того, если вы создадите public static Something в Java, вы создадите это в сопутствующем объекте.

    Я лично нашел их полезными для реализации плагина sbt, который отображает object Blah extends Renderable в файлы blah.html . Узнайте больше о полезности здесь . Я должен был знать, что он реализует эту черту!

    Вы можете использовать companion object s и наследование для некоторого уровня class-lavel или статического полиморфизма.

    Пример 1: Заводы

    Рассмотрим интерфейс

     interface Factory<T> { fun create(): T } 

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

     class Foo { companion object: Factory<Foo> { override fun create() = Foo() } } 

    Теперь мы можем создать функцию расширения для всех заводов для создания и, например, регистрации объекта.

     fun <T> Factory<T>.createAndLog(): T { val t = create() println(t) return t } 

    Не используйте его так

     Foo.createAndLog() 

    Пример 2: Запросы

    Рассмотрим интерфейс маркера

     interface Queryable<T> 

    Теперь у нас есть два класса User и Article которые представляют таблицы в базе данных, companion object реализует интерфейс.

     class User(val id: String) { companion object: Queryable<User> {} } class Article(val authorId: String) { companion object: : Queryable<Article> {} } 

    Теперь мы можем определить функцию расширения для создания запроса из класса

     fun <T> Queryable<T>.query() = db.createQuery<T>() 

    которую мы можем назвать

     User.query() //or Article.query()