Menu
Coddy logo textTech

Declaring Interfaces

Part of the Object Oriented Programming section of Coddy's Kotlin journey. Lesson 22 of 57.

An interface lists what a type can do without saying how. It declares methods and properties that every implementing class must provide. A class implements an interface with a colon, as with a superclass, but without parentheses, because an interface has no 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)
}

Inside main:

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

Output:

circle with radius 3
-----

An interface can declare properties too. The class provides them as constructor properties, stored properties or getters; the interface itself stores nothing:

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"
}

Inside main:

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

Output:

taxi: 4
bike on 2 wheels

Every member the interface declares must be implemented, each with override, or the class does not compile. An interface cannot be instantiated:

interface Speaker {
    fun speak(): String
    val volume: Int
}
// class Mute : Speaker { override fun speak() = "" }   // error: volume is not implemented
// class Loud : Speaker() { ... }                      // error: an interface has no constructor
// val s = Speaker()                                   // error: cannot create an interface

An interface and an abstract class both declare members without a body. An interface has no constructor and no stored state, and a class can implement many interfaces but extend only one class. Use an interface for a capability that unrelated classes share, such as Drawable or Comparable, and an abstract class for a common base with state.

interface Drawable { fun draw(): String }                   // a capability
abstract class Shape(val name: String) { abstract fun area(): Double }   // a base with state
class Square(val s: Double) : Shape("square"), Drawable {  // one class, any interfaces
    override fun area() = s * s
    override fun draw() = "[]"
}
challenge icon

Challenge

Easy

Declare the members of the interface Shape: a read-only property name and the methods area() and perimeter(), both returning Double. Make Rectangle(width, height) (name rectangle) and Circle(radius) (name circle, using Math.PI) implement them. Then complete describe(shape), which returns rectangle: area 12.00, perimeter 14.00 with two decimals, using only members of Shape.

The supplied code reads lines r,3,4 or c,2, creates the matching shape and prints describe(shape).

Your code goes in Shape.kt, Rectangle.kt, Circle.kt and Functions.kt. Main.kt holds the supplied input/output code and cannot be edited.

Try it yourself

fun main() {
    // Supplied input/output code: keep it as it is
    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 iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Kotlin playground