En este tutorial te explicaremos el uso de la palabra reservada object
para crear expresiones de objetos en Kotlin, o también llamados objetos anónimos. Un mecanismo equivalente a la creación de clases anónimas en Java.
Objetos Anónimos
Las expresiones de objetos u objetos anónimos son el reemplazo a las clases internas anónimas de Java.
Su propósito es permitirte declarar una clase y crear una instancia de la misma en una sola expresión asignable. Donde no es necesario asignarle nombre a la clase o a su instancia
Usa la palabra object
y luego declara el cuerpo del mismo para asignar la instancia.
Por ejemplo:
fun main() {
val whileParams = object {
var counter = 0
var condition = true
fun action(param: Int) {
println(param)
counter++
condition = counter < 10
}
}
while (whileParams.condition) {
whileParams.action(Random.nextInt(1, 10))
}
}
En el código anterior hay una expresión de objeto asignada a la variable whileParams
. Esta consta de un objeto con dos propiedades y un método. Su objetivo es mejorar la legibilidad de los parámetros del bucle while en main()
.
counter
representa a un contador usado para determinar la condición de ejecución en condition
.
El método action()
representa la acción del bucle while
. En esta caso es imprimir al parámetro, incrementar a counter
y luego determinar si el bucle debe finalizar al ser menor a 10.
Finalmente se escribe una sentencia while
que accede a whileParams
para tomar la condición y ejecutar en su cuerpo a action()
, la cual recibe un número aleatorio del rango [1,10]
.
Como ves, el objeto se crea dentro de main()
con el fin de aumentar el contexto de nombres para los parámetros del bucle while, por lo que evitamos crear una clase con un nombre y tener que instanciarla.
Implementar Escucha De Eventos
Asignar escuchas en controles de interfaces es un buen ejemplo para crear expresiones de objetos que implementen una interfaz como supertipo.
Considera la interfaz OnQueryTextTextListener
de Android, la cual responde a cambios del texto de búsqueda de un SearchView
.
interface OnQueryTextListener {
fun onQueryTextSubmit(query: String?): Boolean
fun onQueryTextChange(newText: String?): Boolean
}
Para procesar los eventos de cambio del texto sobre el control, obtienes la referencia y luego pasas un anónimo que implemente el tipo y sobrescriba los métodos:
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
// Acciones
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
// Acciones
return false
}
})
Al usar object : SearchView.OnQueryTextListener
, especificamos que la expresión de objeto debe sobrescribir con override
a los métodos abstractos de la interfaz que sirve como tipo.
Lambdas En Lugar De Objetos Anónimos
El uso de expresiones de objetos es perfecto cuando requieres sobrescribir múltiples métodos como en el ejemplo anterior. Sin embargo, si vas a sobrescribir uno solo, es mejor pasar un literal de función como una función lambda.
Kotlin puede convertir una lambda en la implementación de una interfaz con un solo método (SAM o single abstract method).
Tomemos como ejemplo la interfaz View.OnClickListener
en Android, la cual tiene un solo método abstracto llamado onClick()
para procesar el momento en que se dan clicks sobre un view.
interface OnClickListener {
fun onClick(view: View?)
}
Si usamos una expresión de objeto tendríamos sin problemas el código:
view.setOnClickListener(object : View.OnClickListener{
override fun onClick(view: View?) {
TODO("Por implementar")
}
})
Pero el compilador Kotlin en IntelliJ IDEA nos recomendaría aprovechar la característica de convertir el objeto anónimo a una lambda.
Por lo que podemos simplificar la escritura a:
view.setOnClickListener {
TODO("Por implementar")
}