Menu
Coddy logo textTech

Declaración de interfaces

Parte de la sección Programación orientada a objetos del Journey de Kotlin de Coddy. Lección 22 de 57.

Una interfaz enumera lo que un tipo puede hacer sin decir cómo. Declara métodos y propiedades que toda clase que la implemente debe proporcionar. Una clase implementa una interfaz con dos puntos, igual que con una superclase, pero sin paréntesis, porque una interfaz no tiene constructor:

interface Drawable {
    fun draw(): String
}
class Circle(val radius: Int) : Drawable {
    override fun draw() = "circle with radius $radius"
}
class Line(val length: Int) : Drawable {
    override fun draw() = "-".repeat(length)
}

Dentro de main:

println(Circle(3).draw())
println(Line(5).draw())

Salida:

circle with radius 3
-----

Una interfaz también puede declarar propiedades. La clase las proporciona como propiedades del constructor, propiedades almacenadas o getters; la propia interfaz no almacena nada:

interface Vehicle {
    val wheels: Int
    val label: String
}
class Car(override val label: String) : Vehicle {
    override val wheels = 4
}
class Bike : Vehicle {
    override val wheels = 2
    override val label: String
        get() = "bike on $wheels wheels"
}

Dentro de main:

println("${Car("taxi").label}: ${Car("taxi").wheels}")
println(Bike().label)

Salida:

taxi: 4
bike on 2 wheels

Cada miembro que declara la interfaz debe implementarse, cada uno con override, o la clase no compila. Una interfaz no se puede instanciar:

interface Speaker {
    fun speak(): String
    val volume: Int
}
// class Mute : Speaker { override fun speak() = "" }   // error: volume no está implementado
// class Loud : Speaker() { ... }                      // error: una interfaz no tiene constructor
// val s = Speaker()                                   // error: no se puede crear una interfaz

Una interfaz y una clase abstracta declaran miembros sin un cuerpo. Una interfaz no tiene constructor ni estado almacenado, y una clase puede implementar muchas interfaces, pero extender solo una clase. Usa una interfaz para una capacidad que compartan clases no relacionadas, como Drawable o Comparable, y una clase abstracta para una base común con estado.

interface Drawable { fun draw(): String }                   // una capacidad
abstract class Shape(val name: String) { abstract fun area(): Double }   // una base con estado
class Square(val s: Double) : Shape("square"), Drawable {  // una clase, cualesquiera interfaces
    override fun area() = s * s
    override fun draw() = "[]"
}
challenge icon

Desafío

Fácil

Declara los miembros de la interfaz Shape: una propiedad de solo lectura name y los métodos area() y perimeter(), ambos devolviendo Double. Haz que Rectangle(width, height) (con el nombre rectangle) y Circle(radius) (con el nombre circle, usando Math.PI) los implementen. Después completa describe(shape), que devuelve rectangle: area 12.00, perimeter 14.00 con dos decimales, usando únicamente miembros de Shape.

El código proporcionado lee líneas r,3,4 o c,2, crea la forma correspondiente e imprime describe(shape).

Tu código va en Shape.kt, Rectangle.kt, Circle.kt y Functions.kt. Main.kt contiene el código proporcionado de entrada/salida y no se puede editar.

Pruébalo tú mismo

fun main() {
    // Código de entrada/salida suministrado: mantenlo tal como está
    val input = generateSequence(::readLine).toList()
    for (line in input) {
        val p = line.split(",").map { it.trim() }
        val shape: Shape = if (p[0] == "r") Rectangle(p[1].toDouble(), p[2].toDouble()) else Circle(p[1].toDouble())
        println(describe(shape))
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación orientada a objetos

Practica por tu cuenta: Playground de Kotlin