Menu
Coddy logo textTech

オブジェクト宣言

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で値を取得します。それ以外は通常のクラス本体であり、privateな状態、privateなヘルパー、publicなメソッドがあります。

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()           // エラー: オブジェクトにはコンストラクタがありません
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プレイグラウンド