Sobes.tech
Junior

¿Cómo se organiza la herencia y el polimorfismo en Kotlin?

sobes.tech AI

Respuesta de la IA

En Kotlin, la herencia se implementa a través de mecanismos de clases e interfaces. Las clases pueden heredar solo de una clase (herencia simple), pero pueden implementar múltiples interfaces.

Por defecto, todas las clases en Kotlin son 'final', es decir, no pueden ser heredadas. Para permitir la herencia, una clase debe ser explícitamente marcada con la palabra clave open.

Herencia de clases:

open class Shape { // Clase base, marcada como open
    open fun draw() { // Método que puede ser sobrescrito
        println("Dibujando una forma")
    }
}

class Circle : Shape() { // Hereda de Shape
    override fun draw() { // Sobrescribe el método
        println("Dibujando un círculo")
    }
}

En el constructor de la clase hija, es necesario llamar explícitamente o implícitamente al constructor de la clase base.

Interfaces:

Las interfaces en Kotlin son similares a las de Java 8 y pueden contener métodos abstractos y métodos con implementación. Las clases pueden implementar una o varias interfaces.

interface Drawable {
    fun draw() // Método abstracto
    fun description() { // Método con implementación por defecto
        println("Este es un objeto dibujable")
    }
}

class Square : Drawable {
    override fun draw() { // Implementación del método abstracto
        println("Dibujando un cuadrado")
    }
    // description() puede ser sobrescrito, pero no es obligatorio
}

Polimorfismo:

El polimorfismo en Kotlin se logra permitiendo trabajar con objetos de diferentes clases a través de un tipo base común (clase o interfaz). Esto permite llamar a métodos específicos del tipo de objeto en tiempo de ejecución.

fun render(drawable: Drawable) {
    drawable.draw() // Llama al método draw() dependiendo del tipo real del objeto
    drawable.description()
}

fun main() {
    val circle: Shape = Circle() // El objeto Circle se trata como Shape
    circle.draw() // Llama a draw() de Circle gracias al polimorfismo

    val square: Drawable = Square() // El objeto Square se trata como Drawable
    render(square) // Llama a draw() y description() de Square
}

En este ejemplo, render trabaja con cualquier objeto que implemente Drawable. La llamada a drawable.draw() ejecutará la implementación del método draw para el tipo específico del objeto (Square en este caso).

Diferencias entre herencia de clases e implementación de interfaces:

  • Herencia de clase: Establece una relación "es un" (is-a). La clase hija hereda el estado y comportamiento de la clase base.
  • Implementación de interfaz: Define una "capacidad" o "contrato". La clase promete proporcionar la implementación de todos los métodos abstractos de la interfaz.

Tabla comparativa:

Característica Herencia de clase Implementación de interfaz
Tipo de relación es-a Capacidad / Contrato
Múltiples Única Múltiple
Estado Hereda el estado de la clase base No hereda estado
Implementación de métodos Puede contener implementación Puede contener implementación por defecto (desde Java 8)