Companion se beneficia de la posibilidad de implementar interfaces

¿Por qué en Kotlin / Scala los objects complementarios pueden implementar algunas interfaces, qué beneficios puede tener esto? ¿Cuándo es útil usar esta característica?

Debido a que los companion object s son object s, los object pueden implementar interfaces (o extender classs), y no hay una buena razón para rechazarlo para los companion object en particular.

Un uso común en Scala es para fábricas: por ejemplo, Seq , List , Vector , etc. Todos los objects complementarios extienden TraversableFactory para que pueda escribir código que funcione con TraversableFactory y pasar cualquiera de ellos para build el tipo que desee. P.ej

 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) 

Del mismo modo, todos los objects complementarios de la class de caso extienden los types de funciones.

Utiliza un object singleton cuando solo necesita una instancia de class particular en el progtwig.

Por ejemplo, Scala's Nil implementa la List[Nothing] . En lugar de cada tipo de list para implementar su Nil particular, solo hay uno.

En el patrón de class de tipo , donde tiene solo un implicit object para la implementación correspondiente.

Además, donde crearía un object public static Something en Java, lo crearía en un object complementario.

Personalmente los encontré útiles para implementar un plugin sbt, que hace que el object Blah extends Renderable a los files blah.html . Encuentre más acerca de la utilidad aquí . ¡ Tenía que saber que implementa ese rasgo!

Puede usar los companion object y la inheritance para algún nivel de class-lavel o polymorphism estático.

Ejemplo 1: Fábricas

Considera una interfaz

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

Ahora, creamos una class cuyo object compañero lo implementa

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

Ahora podemos crear una function de extensión para todas las fábricas para crear y, por ejemplo, registrar el object.

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

Y úselo como tal

 Foo.createAndLog() 

Ejemplo 2: Consultas

Considere una interfaz de marcador

 interface Queryable<T> 

Ahora tenemos dos classs User y Article que representan tablas en una database cuyo companion object implementa la interfaz.

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

Ahora podemos definir una function de extensión para crear una consulta de la class

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

que podemos llamar como

 User.query() //or Article.query() 
  • Kotlin: llaves de varias expresiones (o declaraciones)
  • Kotlin VS Scala: Implementar methods con parameters constructor primarios
  • ¿Por qué Kotlin comstack más rápido que Scala?
  • Biblioteca Headless de una fuente para JVM y JavaScript
  • Hay alguna biblioteca para trabajar con mónadas en kotlin?
  • Scala require () equivalente en Kotlin
  • Sistema local de administración de packages Java en Python PIP style?
  • Genéricos reificados en Scala 2.10
  • ¿Existe un análogo Future.sequence en kotlin?
  • ¿Cómo hacer que los constructores seguros de Kotlin trabajen en Scala?
  • Tipo de function con receptor en Scala