Introducción

En este tema, exploraremos dos conceptos fundamentales de la Programación Orientada a Objetos (POO) en Kotlin: la herencia y las interfaces. La herencia permite que una clase derive de otra, reutilizando y extendiendo su funcionalidad. Las interfaces, por otro lado, definen un contrato que las clases pueden implementar, asegurando que ciertas funciones estén presentes.

Herencia en Kotlin

Conceptos Clave

  1. Clase Base (Superclase): La clase de la cual se heredan propiedades y métodos.
  2. Clase Derivada (Subclase): La clase que hereda de la clase base.
  3. Modificador open: En Kotlin, las clases y métodos son final por defecto. Para permitir la herencia, se debe marcar la clase base y los métodos que se pueden sobrescribir con el modificador open.

Ejemplo Práctico

// Clase base
open class Animal(val name: String) {
    open fun makeSound() {
        println("$name hace un sonido")
    }
}

// Clase derivada
class Dog(name: String) : Animal(name) {
    override fun makeSound() {
        println("$name ladra")
    }
}

fun main() {
    val myDog = Dog("Rex")
    myDog.makeSound()  // Output: Rex ladra
}

Explicación del Código

  • Clase Animal: Es la clase base con una propiedad name y un método makeSound que imprime un mensaje.
  • Clase Dog: Es una clase derivada que hereda de Animal. Sobrescribe el método makeSound para proporcionar una implementación específica.
  • Uso del Modificador open: La clase Animal y su método makeSound están marcados como open para permitir la herencia y la sobrescritura.

Interfaces en Kotlin

Conceptos Clave

  1. Definición de Interfaz: Una interfaz define un conjunto de métodos y propiedades que una clase debe implementar.
  2. Implementación de Interfaz: Una clase puede implementar una o más interfaces, proporcionando las implementaciones de los métodos definidos en ellas.

Ejemplo Práctico

// Definición de la interfaz
interface Drivable {
    fun drive()
}

// Clase que implementa la interfaz
class Car : Drivable {
    override fun drive() {
        println("El coche está conduciendo")
    }
}

fun main() {
    val myCar = Car()
    myCar.drive()  // Output: El coche está conduciendo
}

Explicación del Código

  • Interfaz Drivable: Define un método drive que las clases deben implementar.
  • Clase Car: Implementa la interfaz Drivable y proporciona una implementación concreta del método drive.

Ejercicio Práctico

Ejercicio 1: Crear una Jerarquía de Clases

  1. Definir una clase base Person con una propiedad name y un método work.
  2. Crear una clase derivada Teacher que sobrescriba el método work para imprimir "Enseñando".
  3. Crear una clase derivada Student que sobrescriba el método work para imprimir "Estudiando".

Solución

// Clase base
open class Person(val name: String) {
    open fun work() {
        println("$name está trabajando")
    }
}

// Clase derivada Teacher
class Teacher(name: String) : Person(name) {
    override fun work() {
        println("$name está enseñando")
    }
}

// Clase derivada Student
class Student(name: String) : Person(name) {
    override fun work() {
        println("$name está estudiando")
    }
}

fun main() {
    val teacher = Teacher("Alice")
    val student = Student("Bob")
    
    teacher.work()  // Output: Alice está enseñando
    student.work()  // Output: Bob está estudiando
}

Ejercicio 2: Implementar una Interfaz

  1. Definir una interfaz Playable con un método play.
  2. Crear una clase Guitar que implemente la interfaz Playable y proporcione una implementación del método play que imprima "Tocando la guitarra".

Solución

// Definición de la interfaz
interface Playable {
    fun play()
}

// Clase que implementa la interfaz
class Guitar : Playable {
    override fun play() {
        println("Tocando la guitarra")
    }
}

fun main() {
    val myGuitar = Guitar()
    myGuitar.play()  // Output: Tocando la guitarra
}

Conclusión

En esta sección, hemos aprendido sobre la herencia y las interfaces en Kotlin. La herencia nos permite reutilizar y extender la funcionalidad de las clases existentes, mientras que las interfaces nos permiten definir contratos que las clases deben cumplir. Estos conceptos son fundamentales para la Programación Orientada a Objetos y son ampliamente utilizados en el desarrollo de software.

En el próximo tema, exploraremos los modificadores de visibilidad en Kotlin, que nos permiten controlar el acceso a las propiedades y métodos de nuestras clases.

© Copyright 2024. Todos los derechos reservados