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 zipToda alternativa
  • Convierta la function de Scala a la function de Kotlin
  • ¿Es posible express kotlin 'con' método equivalente en Scala?
  • Kotlin VS Scala: Implementar methods con parameters constructor primarios
  • Scala require () equivalente en Kotlin
  • ¿Por qué el comstackdor de Scala me da un error al pasar una class sellada de Kotlin a un constructor?
  • Sistema local de administración de packages Java en Python PIP style?
  • ¿Por qué Kotlin comstack más rápido que Scala?
  • Progtwigción funcional: cómo continuar el context para una cadena de reglas de validation
  • Herencia genérica de Kotlin
  • ¿Cómo hacer que los constructores seguros de Kotlin trabajen en Scala?