Clases abstractas

Clases abstractas en Kotlin

En la entrada sobre la herencia de clases ya vimos de pasada las clases abstractas en cuanto que son un tipo de clases que no necesitan la anotación con open para ser heredadas por otras clases (al ser abstract, por defecto ya son open), y ahora vamos a detenernos un poco más en este tipo de clases.

Una clase abstracta es aquella que no implementa alguno de sus métodos y se declara con la palabra reservada o modificador abstract. Se trata de clases de las que no se crean objetos directamente sino a través de sus clases derivadas desde las cuales sí se pueden instanciar objetos, y en contraposición a las clases abstractas se dice que son clases concretas. De hecho, una clase abstracta solo se utiliza para definir subclases.

Además de la clase, también sus miembros sin implementación pueden ser declarados abstractos (aunque no necesariamente todos), y por lo tanto la clase hija debe implementar estos métodos y propiedades definidos en la clase abstracta. Recuerda que toda clase que contenga algún método abstracto también es abstracta, y por tanto hay que etiquetarla con abstract.

Más claro en un ejemplo:
// Clase abstracta
abstract class Figura(val nombre: String) {

    // función abstracta
    abstract fun area(): Double

    // función miembro
    fun formateaResultado(total: Double): String {
        return "${"%.2f".format(total)}"
    }
}

// Clase derivada o concreta que hereda de la clase abstracta
class Circulo(nombre: String, val radio: Double): Figura(nombre) {

    // implementa la función abstracta de la clase padre
    override fun area() = Math.PI * Math.pow(radio, 2.0)
}

fun main(args: Array<String>) {
    val circulo = Circulo("círculo", 5.0)
    println("El ${circulo.nombre} con radio ${circulo.radio} " +
            "tiene un área de ${circulo.formateaResultado(circulo.area())}")
    // El círculo con radio 5.0 tiene un área de 78.54
}
Como se observa en el código anterior, una función abstracta no requiere especificar ningún valor de retorno, por lo que necesariamente deberá ser sobrescrito por la clase hija.

Un par de ejemplos más para ilustrar el uso de clases abstractas:
abstract class Aritmetica(val valor1: Int, val valor2: Int) {
    var resultado: Int = 0

    abstract fun calcular()

    fun mostrar(simb: String) {
        println("$valor1 $simb $valor2 = $resultado")
    }
}

class Suma(valor1: Int, valor2: Int): Aritmetica(valor1, valor2) {
    override fun calcular() {
        resultado = valor1 + valor2
    }
}

class Resta(valor1: Int, valor2: Int): Aritmetica(valor1, valor2) {
    override fun calcular() {
        resultado = valor1 - valor2
    }
}

fun main(args: Array<String>) {
    val suma = Suma(8, 7)
    suma.calcular()
    suma.mostrar("+") // 8 + 7 = 15
    val resta = Resta(9, 4)
    resta.calcular()
    resta.mostrar("-") // 9 - 4 = 5
}

abstract class Contacto(nombre: String) {

    init {
        println("Nombre: $nombre")
    }

    fun muestraTelefono(tfno: Long) {
        println("Teléfono: $tfno")
    }

    abstract fun muestraGrupo(grupo: String)
}

class Persona(nombre: String): Contacto(nombre) {

    override fun muestraGrupo(grupo: String) {
        println("Grupo: $grupo")
    }
}

fun main() {
    val persona = Persona("Juan Palomo")
    persona.muestraTelefono(3491123456)
    persona.muestraGrupo("Familia")
}

Comentarios

Entradas populares

I/O: entrada y salida de datos en consola

Recursos gratis para aprender Kotlin

Lectura y escritura de archivos