Menu
Coddy logo textTech

セカンダリコンストラクタ

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

クラスは、セカンダリコンストラクタを使って、作成方法を追加できます。セカンダリコンストラクタは constructor で宣言します。それぞれが this(...) を使ってプライマリコンストラクタを呼び出す必要があります。

class Temperature(val celsius: Double) {
    constructor(fahrenheit: Int) : this((fahrenheit - 32) * 5 / 9.0)
}

main の中で:

println(Temperature(20.0).celsius)
println(Temperature(212).celsius)

出力:

20.0
100.0

デフォルト引数を使うと、セカンダリコンストラクタが不要になることがよくあります。デフォルト値を持つ1つのプライマリコンストラクタを優先し、テキストを解析する場合のように、入力の形が異なるときはセカンダリコンストラクタを使用します。

class Color(val r: Int, val g: Int, val b: Int) {
    constructor(gray: Int) : this(gray, gray, gray)
    constructor(hex: String) : this(hex.substring(0, 2).toInt(16), hex.substring(2, 4).toInt(16), hex.substring(4, 6).toInt(16))

    fun label() = "rgb($r, $g, $b)"
}

main の中で:

println(Color(128).label())
println(Color("FF8000").label())

出力:

rgb(128, 128, 128)
rgb(255, 128, 0)

プライマリコンストラクターとそのinitブロックが最初に実行され、その後にセカンダリコンストラクターの本体が実行されます:

class Log(val name: String) {
    init { println("primary: $name") }
    constructor(id: Int) : this("log-$id") {
        println("secondary: $id")
    }
}

mainの内部:

Log(7)

出力:

primary: log-7
secondary: 7

コンストラクターは、すべてのオーバーロードで曖昧さなく機能しなければなりません。同じパラメーター型を持つ2つのコンストラクターは許可されず、複数のコンストラクターに一致する可能性がある呼び出しはコンパイルできません。

class Size(val w: Int, val h: Int) {
    constructor(side: Int) : this(side, side)   // Size(3) -> 正方形
    // constructor(w: Int) : this(w, 1)        // error: 上記と同じシグネチャ
}
challenge icon

チャレンジ

簡単

クラス Duration(val seconds: Int) を、(minutes: Int, seconds: Int) を受け取るセカンダリコンストラクターと、1:30 や 2:05:10(時:分:秒)のようなテキストを受け取るもう1つのコンストラクターで完成させてください。2桁の分と秒を使った h:mm:ss を返す format() を追加してください。

提供されたコードは、1つまたは2つのコロンを含むテキストとして時間を読み取り、それぞれをテキストコンストラクターで作成して format() を出力し、その後に total と整形された合計を出力します。

コードは Duration.kt に記述してください。Main.kt には提供された入出力コードが含まれており、編集できません。

自分で試してみよう

fun main() {
    // 提供された入出力コード: そのままにしておく
    val input = generateSequence(::readLine).toList()
    var total = 0
    for (line in input) {
        val d = Duration(line)
        println(d.format())
        total += d.seconds
    }
    println("total " + Duration(total).format())
}
quiz icon腕試し

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

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

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