Herencia de clases



En la programación orientada a objetos la herencia de clases nos permite declarar una jerarquía de clases, y al hacerlo podemos tomar componentes de una clase base (superclase o clase padre) y reutilizarlos en las clases derivadas (subclases o clases hijas), las cuales además definen sus propias propiedades y métodos particulares.

En Kotlin para declarar esta jerarquía o herencia de clases se utiliza la siguiente sintaxis (para que una clase sea heredable debemos anteponer la palabra reservada open):
open class Base(p: Int)

class Derivada(p: Int): Base(p)
Igualmente si queremos que una propiedad o un método de la clase base se puedan reescribir en una clase derivada (para modificar o extender su comportamiento) debemos etiquetarlos con la palabra open, y entonces en la clase derivada podemos sobreescribir esas propiedades (de un tipo compatible) y esos métodos de la clase base utilizando el modificador override.

En el siguiente código vemos un ejemplo de herencia de clase:
// clase Base
open class Dado {
    
    var valor: Int = 1
    
    open val juego = "parchís"
    
    open fun tirar() {       
        valor = ((Math.random () * 6) + 1) .toInt ()
    }
    
    fun mostrar () {
        println ("El dado de $juego ha sacado $valor")
    }
}

// clase Derivada que hereda propiedades y métodos de la clase Dado
class DadoRol: Dado() { 

    override val juego = "rol" // reescribe la propiedad juego
    
    override fun tirar() { // modifica el método tirar
        valor = ((Math.random () * 8) + 1) .toInt ()
    }        
}

fun main (args: Array <String>) {        
    
    val dado1 = Dado()
    dado1.tirar()
    dado1.mostrar()

    val dado2 = DadoRol()
    dado2.tirar()
    dado2.mostrar()
}

Una clase, y sus miembros sin implementación en la clase, pueden ser declarados abstractos con la palabra reservada abstract, y en estos casos no es necesario anotar una clase o una función abstractas con open:
abstract class Forma(val nombre: String) {
   
   abstract fun area(): Double

   fun muestraResultado(){
       println("El ${nombre} tiene un área de ${"%.2f".format(area())}")
   }
}

class Cuadrado(nombre: String, val lado: Double): Forma(nombre) {
    override fun area() = lado * lado
}

class Circulo(nombre: String, val radio: Double): Forma(nombre) {
   override fun area() = Math.PI * Math.pow(radio, 2.0)      
}

fun main(args: Array<String>) {
   
   val cuadrado = Cuadrado("Cuadrado", 3.5)
   cuadrado.muestraResultado() // El Cuadrado tiene un área de 12.25
   
    
   val circulo = Circulo("Círculo", 4.0)   
   circulo.muestraResultado() // El Círculo tiene un área de 50.27
}

Otro ejemplo de herencia de clases (la palabra reservada super permite llamar a una propiedad o a un método de la clase base):
open class Persona(val nombre: String, var edad: Int) {

    open val enPlantilla = false

    open fun imprimir() {
        println("Nombre: $nombre - Edad: $edad")
        if (enPlantilla) {
            println("Actualmente en plantilla")
        } else {
            println("Sin relación laboral con la empresa\n")
        }
    }
}

class Empleado(
    nombre: String,
    edad: Int,
    var sueldo: Double
) : Persona(nombre, edad) {

    override val enPlantilla = true

    override fun imprimir() {
        super.imprimir() // llama al método imprimir de la clase padre
        print("Sueldo: $sueldo €")
    }

    fun calcularRetencion() { // método específico de la clase derivada
        val retencion = when {
            sueldo > 5500.0 -> 24
            sueldo > 3500.0 -> 19
            else -> 0
        }
        if (retencion != 0) {
            val IRPF = (sueldo * retencion) / 100
            print(" - $IRPF € de IRPF = ${sueldo - IRPF} €")
        }
        println("\n")
    }
}

fun main() {
    val persona1 = Persona("Juan", 21)
    persona1.imprimir()

    val empleado1 = Empleado("Pepe", 32, 2425.25)
    empleado1.imprimir()
    empleado1.calcularRetencion()

    val empleado2 = Empleado("Luisa", 56, 4158.50)
    empleado2.imprimir()
    empleado2.calcularRetencion()
}
Nombre: Juan - Edad: 21
Sin relación laboral con la empresa

Nombre: Pepe - Edad: 32
Actualmente en plantilla
Sueldo: 2425.25 €

Nombre: Luisa - Edad: 56
Actualmente en plantilla
Sueldo: 4158.5 € - 790.115 € de IRPF = 3368.385 €

Comentarios

Entradas populares

I/O: entrada y salida de datos en consola

Recursos gratis para aprender Kotlin

Lectura y escritura de archivos