Los Companion Objects para manejar los Static de Java en Kotlin

24-05-2018 - Andrés Cruz

In english

En esta entrada seguiremos nuestros tutoriales sobre Kotlin detallando características que lo hacen un lenguaje moderno para el desarrollo de aplicaciones; su codificación simple, sencilla, directa y concisa ayuda mucho en los tiempos y el entendimiento en general del código; un ejemplo de código conciso lo veremos a continuación con el uso de los companion objects que viene siendo la forma en la que Kotlin trabaja con los static de Java; otro enfoque que le puedes colocar, son las famosas clases tipo singleton que son empleadas mucho pero mucho en las aplicaciones como lo es el caso de Android que es nuestro especial interés.

Ejemplo del funcionamiento del Companion Objects en Kotlin

Para emplear los Companion Objects en Kotlin los mismos deben ser declarados dentro de la instancia de una clase de la siguiente forma:

class Persona {

   companion object Raza {

       // clasificacion persona
       val edades: IntArray = intArrayOf(0, 2, 30, 60)
       var razas =
               arrayOf("Europeo", "Asiatico", "Latino", "Arabe", "Africano", "Americano", "Canadiense")
       var clasificacion = "Clasificación personas"

       init {
           println("Inicializando el companion")
       }

       fun enAmerica(): Array<String> {
           return arrayOf(razas[2], razas[5], razas[6])
       }

       fun adultoMayor(): Int {
           return edades[3]
       }

       fun printClasificacion() {
           println(clasificacion)
       }
   }
}

En primera instancia, pareciera que emplear una estructura más compleja, ya que estamos anidando elementos, en este caso nuestra clase dentro de un Companion Object, y es verdad, pero gana en legibilidad, ya que es muy común que queramos definir un bloque importante como static, y no tenemos que estar colocando cada rato la palabra static para definir múltiples funciones, o parámetros como hacíamos en Java, con el englobamiento que hacemos con el Companion Object es más que suficiente para englobar todos nuestros métodos y propiedades estáticas de una sola vez; en Java tendríamos que hacer lo siguiente.

public static final String KEY = "key";

Ahora, si tenemos varias estructuras y variables que queramos que sean static, entonces todo se nos complica bastante, porque tenemos que estar colocando static a cada rato, y si además tenemos métodos y atributos que no son estáticos, a la final lo que tenemos es una buena mezcla de varias cosas; cosa que no sucede con Kotlin al englobar en un bloque de código las propiedades y funciones que queramos sean estáticas mediante los Companion Objects.

En el ejemplo anterior, podemos apreciar que declaramos nuestro Companion Object dentro de la clase Persona, como principio fundamental, para crear y posteriormente usar un Companion Object el mismo debe de estar declarado dentro de una clase como hicimos anteriormente, que declaramos el Companion Object llamado Raza dentro de la clase madre Persona.

Accediendo a los métodos del Companion Object

Con el Companion Object ya declarado, creamos algunas propiedades como lo son edades y razas que son Arrays las cuales creamos método personalizados para cada ámbito en este ejemplo, es decir, creamos como ejemplo un método enAmerica() que retorna un Array con las razas nativas del continente Americano, que serían las de los latinos, los Americanos (américa del norte) y los canadienses.

Hacemos algo parecido con las edades, la cual creamos un método llamado adultoMayor() que retorna las edad en la que se considera que a partir de la misma, la persona es un adulto mayor.

Además creamos un texto mediante una variable llamada clasificacion que retorna su valor mediante el método printClasificacion.

Por último, podemos emplear un constructor definido como init en caso de que sea necesario.

Variaciones en la estructura del Companion Object para manejar los static

Podemos omitir el nombre del Companion Object de la declaración, quedando de la siguiente forma:

class Persona {

   companion object {

       // clasificacion persona
       val edades: IntArray = intArrayOf(0, 2, 30, 60)
       var razas =
               arrayOf("Europeo", "Asiatico", "Latino", "Arabe", "Africano", "Americano", "Canadiense")
       var clasificacion = "Clasificación personas"

/*Demas metodos*/

}

Para poder emplear métodos o propiedades del Companion Object empleamos el siguiente esquema; tomando como ejemplo el código anterior, tenemos que:

println(Persona.enAmerica()[0]) println(Persona.printClasificacion()) println(Persona.adultoMayor()) }

Accediendo a las propiedades del Companion Object

Para referenciar los métodos que vimos anteriormente; por supuesto, podemos referencias directamente las propiedades como hemos hecho en anteriores entradas, y esto es excelente, ya que no tenemos que estar creados los famosos métodos get y set para cada propiedad de nuestro objeto; con declarar la propiedad y su tipo es condición necesaria y suficiente:

Persona.edades
Persona.razas
Persona.clasificacion

Como podemos ver, debemos emplear el nombre de la clase madre seguido del método o propiedad definido dentro del Companion Object, es el mismo enfoque que el realizado en Java al momento de referenciar a un método o propiedad de una clase estática en Java; es decir, primero referenciamos el nombre de la clase para luego referenciar el método o propiedad que del Companion Object sin la necesidad de crear un objeto de la clase.

Métodos de la clase madre del Companion Object

Podemos definir la estructura de nuestra clase como queramos, tomando como referencia la estructura que vimos en una anterior entrada:

Clases en Kotlin: clases vacías, constructores y propiedades

Tenemos que nuestro código quedaría así:

class Persona {

   var nombre: String = ""
   var apellido: String = ""
   var edad: Int = 0

   init {
       this.nombre = nombre
       this.apellido = apellido
       this.edad = edad
   }

   companion object Raza {

       // clasificacion persona
       val edades: IntArray = intArrayOf(0, 2, 30, 60)
       var razas =
               arrayOf("Europeo", "Asiatico", "Latino", "Arabe", "Africano", "Americano", "Canadiense")
       var clasificacion = "Clasificación personas"

       init {
           println("Inicializando el companion")
       }

       fun enAmerica(): Array<String> {
           return arrayOf(razas[2], razas[5], razas[6])
       }

       fun adultoMayor(): Int {
           return edades[3]
       }

       fun printClasificacion() {
           println(clasificacion)
       }
   }
}

Creando una clase Singleton

Todos los ejemplos que vimos anteriormente son clases Singleton, que por definición son clases con una sola instancia en todo el ámbito de la aplicación; son ampliamente utilizadas para tener una sola conexión con la base de datos y evitar saturar o las famosas condiciones de carrera (cómo nos podría pasar en Android con las base de datos de SQLite), datos de usuarios y un largo etc.

Conclusiones

Como puedes ver, los Companion Objects son muy útiles cuando trabajamos con estructuras que deben tener una instancia única, como dados de usuarios, o datos de conexión a la base de datos en Android.

Puedes consultar la documentación oficial en el siguiente enlace: Companion Objects


Andrés Cruz
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.

!Cursos a!

10$

En Udemy

Quedan 5 días!

Ver los cursos
¡Hazte afiliado en Gumroad!

!Cursos desde!

4$

En Academia

Ver los cursos

!Libros desde!

1$

Ver los libros
!Web Alojada en Hostinger!