Menu
Coddy logo textTech

インターフェースの宣言

CoddyのKotlinジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 22/57。

インターフェースは、どのように実行するかを説明せずに、型ができることを一覧にします。実装するすべてのクラスが提供しなければならないメソッドとプロパティを宣言します。クラスはスーパークラスの場合と同じようにコロンを使ってインターフェースを実装しますが、インターフェースにはコンストラクターがないため、かっこは付けません:

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

mainの中では:

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

出力:

circle with radius 3
-----

インターフェースではプロパティも宣言できます。クラスはそれらをコンストラクター・プロパティ、格納プロパティ、またはゲッターとして提供します。インターフェース自体は何も格納しません。

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

main の中では、次のようにします。

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

出力:

taxi: 4
bike on 2 wheels

インターフェースが宣言するすべてのメンバーは、それぞれ override を付けて実装する必要があります。そうしないとクラスはコンパイルできません。インターフェースをインスタンス化することはできません。

interface Speaker {
    fun speak(): String
    val volume: Int
}
// class Mute : Speaker { override fun speak() = "" }   // error: volume が実装されていません
// class Loud : Speaker() { ... }                      // error: インターフェースにはコンストラクタがありません
// val s = Speaker()                                   // error: インターフェースを作成できません

インターフェースと抽象クラスは、どちらも本体を持たないメンバーを宣言します。インターフェースにはコンストラクターも保持された状態もなく、クラスは複数のインターフェースを実装できますが、継承できるクラスは1つだけです。DrawableやComparableのように、関係のないクラスが共有する能力にはインターフェースを使用し、状態を持つ共通の基底クラスには抽象クラスを使用します。

interface Drawable { fun draw(): String }                   // 能力
abstract class Shape(val name: String) { abstract fun area(): Double }   // 状態を持つ基底
class Square(val s: Double) : Shape("square"), Drawable {  // 1つのクラス、任意のインターフェース
    override fun area() = s * s
    override fun draw() = "[]"
}
challenge icon

チャレンジ

簡単

インターフェース Shape のメンバーを宣言します。読み取り専用プロパティ name と、どちらも Double を返すメソッド area() および perimeter() です。Rectangle(width, height)(名前は rectangle)と Circle(radius)(名前は circle、Math.PI を使用)でそれらを実装します。次に、2 桁の小数を使用して rectangle: area 12.00, perimeter 14.00 を返し、Shape のメンバーだけを使用する describe(shape) を完成させます。

提供されたコードは r,3,4 または c,2 の行を読み取り、対応する図形を作成して describe(shape) を出力します。

コードは Shape.kt、Rectangle.kt、Circle.kt、Functions.kt に記述します。Main.kt には提供された入出力コードが含まれており、編集できません。

自分で試してみよう

fun main() {
    // 提供された入力/出力コード: そのままにしておく
    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 icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Kotlinプレイグラウンド