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
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter