En Kotlin, una clase puede tener un constructor primario y tantos constructores secundarios como se deseen. La diferencia con Java es que en Kotlin el constructor primario se declara en la cabecera de la clase y puede contener parámetros y modificadores. Los constructores secundarios siempre deben llamar a otro constructor secundario, al constructor primario o al constructor de la superclase (a través de la palabra clave super).
Características clave:
: super(...).super(...) o de otro constructor secundario/primario.Ejemplo de uso con herencia:
open class A(val a: Int) { constructor(a: Int, str: String) : this(a) { println("Secundario en A: $str") } } class B : A { constructor(a: Int) : super(a) { println("Secundario en B") } constructor(a: Int, s: String) : super(a, s) { println("Secundario #2 en B") } }
¿En qué se diferencia el enfoque de Java?:
¿Se puede en Kotlin crear una clase derivada SIN llamar explícitamente al constructor de la superclase, si en la clase base solo hay un constructor definido?
Respuesta: No, a diferencia de Java, en Kotlin la llamada al constructor de la superclase es obligatoria y se indica explícitamente en la "cabeza" de la clase o después de la palabra clave : super().
Ejemplo de error:
open class Base(val x: Int) class Derived : Base // ¡Error de compilación!
Historia
En un proyecto de microservicios, después de migrar a Kotlin, olvidaron la indicación explícita del constructor padre: el constructor de la superclase con un parámetro obligatorio no fue llamado, el servicio no compiló, y se necesitó refactorizar las firmas.
Historia
Un proyecto de Android tenía una profunda jerarquía (Activity → BaseActivity → CustomActivity), la adición de un constructor secundario perdía parámetros, al final se llamaba al constructor base incorrecto y parte de los campos quedaba null — la aplicación caía en tiempo de ejecución con NPE.
Historia
En un código de biblioteca abierto, un constructor secundario en la clase derivada evitó accidentalmente el constructor primario, lo que condujo a dos ramas diferentes de inicialización: a veces el campo se inicializaba, a veces no. El error fue encontrado solo después de mucho tiempo debido a complejos informes de errores.