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

只有一个实例,因此程序中使用该对象的各个部分都会读取和修改同一状态。对象会在首次使用时创建,如下方的 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

在程序中,只有一个实例的内容适合用对象表示:例如注册表、配置或一组辅助函数。对象属于全局状态,任何文件都可以修改它,因此要将设置器设为私有,并让它的方法检查每次修改。

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</code),每遇到一个 <code>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 在线编辑器