ProgramaciónDesarrollador de Kotlin

¿Cuáles son las diferencias entre clases normales, clases abstractas e interfaces en Kotlin, cuándo y qué herramienta aplicar?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

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:

  • Clase normal: define la estructura y el comportamiento. Se puede heredar si se declara como open.
  • Clase abstracta: no se puede crear directamente. Puede contener implementación y/o métodos abstractos (sin cuerpo).
  • Interfaz: implícitamente abierta, implementa contratos, permite la implementación de métodos, pero no mantiene estado (sólo propiedades sin backing field).

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:

  • Las interfaces permiten la implementación múltiple, las clases abstractas solo una
  • Las interfaces no pueden almacenar estado, las clases abstractas pueden
  • Una clase abstracta puede implementar parte de las interfaces y contener su propia lógica común

Preguntas complicadas.

¿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.

Errores comunes y antipatrón

  • Uso de una clase abstracta en lugar de una interfaz sin necesidad
  • Almacenar estado en una interfaz (imposible, pero se cometen errores en el diseño)
  • Diseñar jerarquías de clases que dificultan la extensión

Ejemplo de la vida real

Caso negativo

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:

  • Un solo punto de cambio para la lógica común

Desventajas:

  • Problemas con la herencia múltiple, difícil integración con otras estructuras

Caso positivo

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:

  • Extensión flexible, modularidad, contratos claros

Desventajas:

  • Requiere diseño en una etapa temprana