Los objects de Kotlin son otro de los elementos del lenguaje al que no estamos acostumbrados los desarrolladores en Android, porque no hay nada parecido en Java.
En realidad un object no es más que un tipo de datos con una única implementación. Por lo que si queremos sacarle algún parecido, éste sería el patrón Singleton de Java. En un momento los compararemos.
Si quieres aprender cuál es la situación de Kotlin en el mercado, por qué debes aprenderlo y los primeros pasos para que veas lo fácil que es, he preparado un training gratuito de hora y media al que puedes unirte haciendo click aquí.
Singleton vs object
El singleton en Java no es tan fácil de implementar como parece. Uno podría pensar que es tan sencillo como esto:
public class Singleton { private Singleton() { } private static Singleton instance; public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
Pero este código es peligroso, sobre todo si se utiliza en distintos hilos. Si dos hilos acceden a la vez a este singleton, se podrían generar dos instancias de este objeto. Un código más correcto sería:
public class Singleton { private static Singleton instance = null; private Singleton(){ } private synchronized static void createInstance() { if (instance == null) { instance = new Singleton(); } } public static Singleton getInstance() { if (instance == null) createInstance(); return instance; } }
Como ves, necesitas unas cuantas líneas para crear un Singleton válido.
¿Cuál sería el equivalente en Kotlin?
object Singleton
No necesitas más.
Declaración de objetos
Declarar un objeto es tan sencillo como declarar una clase. La nomenclatura es la misma.
Vamos a declarar por ejemplo un objeto que implemente un helper de base de datos:
object MySQLOpenHandler : SQLiteOpenHelper(App.instance, "MyDB", null, 1) { override fun onCreate(db: SQLiteDatabase?) { } override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { } }
El objeto se instancia la primera vez que se llama.
Companion Object
Toda clase puede tener un companion object, que es un objeto que es común a todas las instancias de esa clase. Vendría a ser similar a los campos estáticos en Java.
Un ejemplo de implementación:
class App : Application() { companion object { lateinit var instance: App private set } override fun onCreate() { super.onCreate() instance = this } }
En este caso estoy creando una clase que extiende de Application
y que almacena en el companion object
su única instancia.
El lateinit
indica que esa propiedad no va a tener valor desde el principio, pero que se hará antes de que se use (en otro caso lanzará una excepción).
El private set
se usa para que no se pueda asignar un valor desde otra clase que no sea esta.
Nota: Puedes pensar que tendría bastante sentido que
App
fuera un object en vez de una clase. Y así es, pero debido a la forma que el framework de Android tiene de instanciar las clases, si lo intentas verás que la aplicación lanza una excepción nada más lanzarse. Necesitarás queApp
sea una clase, y crearte este pequeño Singleton si quieres acceder a ella.
Expresiones object
Los objects también se pueden utilizar para crear implementaciones anónimas de clases.
Un ejemplo:
recycler.adapter = object : RecyclerView.Adapter() { override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) { } override fun getItemCount(): Int { } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder { } }
Pero un object también puede representar una clase que no existe. Puedes crearla al vuelo:
val newObj = object { var x = "a" var y = "b" } Log.d(tag, "x:${newObj.x}, y:${newObj.y}")
Conclusión
Los objects son un concepto nuevo para los que venimos de Java 6, pero hay muchas ideas que se pueden asociar con otras ya existentes, así que te harás rápido con ellos.
Si te gusta lo que has visto, te animo a que te apuntes al training gratuito, donde te contaré todo lo que necesitas para aprender a crear tus Apps Android en Kotlin desde cero.
Excelente trabajo, entendí bien.
Gracias!