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 wheelsEvery 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 interfaceAn 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
EasyDeclare 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))
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesPrimary Constructorsinit Blocks and ValidationSecondary ConstructorsRecap - Library Card4Inheritance
Open Classes and SubclassesOverriding Memberssuper and ConstructorsAbstract ClassesRecap - Staff Directory2Properties and Encapsulation
Custom AccessorsVisibility ModifiersPrivate Setterslazy and lateinitRecap - Bank Account5Interfaces
Declaring InterfacesDefault MethodsMultiple InterfacesInterfaces as TypesRecap - Payment Methods8Generics
Generic FunctionsGeneric ClassesType ConstraintsVariance With in and outRecap - Priority Queue11Project: Library Management
Books and MembersBorrowing BooksPractice on your own: Kotlin playground