次构造函数
本课属于 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默认参数通常可以避免使用次构造函数。优先使用一个带默认值的主构造函数;当输入形式不同时,例如需要解析文本时,再使用次构造函数:
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每个重载都必须能明确匹配构造函数。不能有两个参数类型相同的构造函数,而且无法明确匹配到某个构造函数的调用会导致编译失败。
class Size(val w: Int, val h: Int) {
constructor(side: Int) : this(side, side) // Size(3) -> 一个正方形
// constructor(w: Int) : this(w, 1) // 错误:与上面的签名相同
}挑战
简单请补全类 Duration(val seconds: Int),添加一个次构造函数 (minutes: Int, seconds: Int),以及另一个接收文本的构造函数,例如 1:30 或 2:05:10(小时:分钟:秒)。添加 format(),使其返回格式为 h:mm:ss 的字符串,其中分钟和秒都用两位数字表示。
提供的代码会读取包含一个或两个冒号的文本时长,使用文本构造函数创建每个时长并打印 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())
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Kotlin 在线编辑器