Menu
CoddyTech

オブジェクト宣言

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

object Name { ... }は、クラスとその唯一のインスタンスを一度に宣言します。名前を使ってオブジェクトを利用します。呼び出すコンストラクターはありません。

object AppConfig {
    var theme = "light"
    val version = "1.4"

    fun describe() = "v$version, $theme theme"
}

mainの中で:

println(AppConfig.describe())
AppConfig.theme = "dark"
println(AppConfig.describe())

出力:

v1.4, light theme
v1.4, dark theme

インスタンスは1つだけなので、オブジェクトを使うプログラムのすべての部分が、同じ状態を読み取り、変更します。オブジェクトは初めて使われたときに作成されます。以下のinitブロックでそのことがわかります。

object Visits {
    var count = 0
        private set

    init { println("Visits created") }

    fun record() { count++ }
}

fun home() = Visits.record()
fun about() { Visits.record(); Visits.record() }

mainの中では:

println("start")
home()
about()
println(Visits.count)

出力:

start
Visits created
3

オブジェクトにはコンストラクターがありません。なぜなら、誰もそれを生成しないからです。プロパティは宣言時またはinitで値を取得します。それ以外は通常のクラス本体と同じです。プライベートな状態、プライベートなヘルパー、パブリックなメソッドがあります。

object IdGenerator {
    private var next = 1

    fun newId(prefix: String) = "$prefix-${pad(next++)}"

    private fun pad(n: Int) = n.toString().padStart(3, '0')
}

mainの中では:

println(IdGenerator.newId("user"))
println(IdGenerator.newId("order"))

出力:

user-001
order-002

プログラム内にただ1つだけ存在するもの、たとえばレジストリ、設定、ヘルパー関数のグループにはオブジェクトを使います。オブジェクトはどのファイルからでも変更できるグローバル状態なので、セッターは非公開にし、メソッドで変更をすべてチェックするようにします。

object Units {
    fun kmToMiles(km: Double) = km * 0.621371
}
Units.kmToMiles(10.0)        // 名前を使って呼び出す
// val u = Units()           // エラー: objectにはコンストラクタがない
challenge icon

チャレンジ

簡単

オブジェクト Leaderboard を完成させてください。各プレイヤーのポイントをプライベートなマップに保持します。add(player, points) はポイントを加算し、top() は首位のプレイヤーを ada 6 の形式で返します(ポイントが同じ場合は、アルファベット順で先に来る名前)。誰もポイントを持っていない場合は empty を返します。reset() は全員を削除し、プロパティ players はプレイヤーの人数を表します。

Functions.kt のヘルパー関数 recordWin と recordDraw はあらかじめ用意されています。これらは別のファイルにある Leaderboard を使用します。用意されたコードは win ada、draw ada bo、top または reset のコマンドを読み取り、各 top に対して top() を出力し、最後に人数とともに players: を出力します。

コードは Leaderboard.kt と Functions.kt に記述します。Main.kt には用意された入出力コードが含まれており、編集できません。

自分で試してみよう

fun main() {
    // 提供された入出力コード:そのままにしてください
    val input = generateSequence(::readLine).toList()
    for (cmd in input) {
        val p = cmd.split(" ")
        when (p[0]) {
            "win" -> recordWin(p[1])
            "draw" -> recordDraw(p[1], p[2])
            "reset" -> Leaderboard.reset()
            else -> println(Leaderboard.top())
        }
    }
    println("players: ${Leaderboard.players}")
}
quiz icon腕試し

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

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

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