Historia de la pregunta:
Kotlin ha combinado lo mejor de Java y el legado funcional de la JVM. Las clases normales se declaran como estructuras estándar, las clases abstractas permiten crear plantillas subdefinidas con implementaciones por defecto, y las interfaces soportan la herencia múltiple de comportamientos sin estado.
Problema:
La elección correcta entre una clase, una clase abstracta y una interfaz determina la arquitectura de la aplicación, la granularidad del código y su extensibilidad. La herencia incorrecta conduce a la complejidad en las pruebas y a futuros cambios.
Solución:
En Kotlin:
Ejemplo de código:
interface Drawable { fun draw() } abstract class Shape(var color: String) : Drawable { abstract fun calcArea(): Double override fun draw() = println("Shape drawn") } class Circle(color: String, val radius: Double) : Shape(color) { override fun calcArea() = Math.PI * radius * radius }
Características clave:
¿Pueden las interfaces contener propiedades con backing field?
No, solo pueden definir la firma de la propiedad, pero no almacenar datos: propiedades sin backing field.
¿Se puede heredar de múltiples clases?
No, Kotlin solo soporta la herencia única de clases, pero la implementación múltiple de interfaces.
¿Se puede declarar un constructor en una interfaz?
No, una interfaz no soporta constructores porque no mantiene estado: solo el contrato de comportamiento.
En la aplicación se trasladaron todas las funciones comunes a una clase abstracta, incluso si no había lógica interna o estado, y la necesidad era solo un contrato común.
Ventajas:
Desventajas:
Solo se trasladaron los contratos necesarios a las interfaces, limitando las clases abstractas a propiedades y métodos comunes que requerían implementación.
Ventajas:
Desventajas: