第二部分:面向对象编程与 Kotlin 特性
第 5 章:类与对象
5.2 构造函数(主构造函数与次构造函数)
在 Kotlin 中,构造函数分为主构造函数(Primary Constructor)和次构造函数(Secondary Constructor),它们用于初始化类的实例。Kotlin 的构造函数设计比 Java 更简洁且功能更强大。
1. 主构造函数
主构造函数是类头的一部分,直接跟在类名后,使用 constructor 关键字声明(如果无注解或可见性修饰符,可省略)。主构造函数的主要作用是:
- 定义类属性(通过参数直接声明属性)。
- 初始化逻辑(通过
init代码块)。
语法示例:
class Person constructor(val name: String, var age: Int) {
// 类体
}
如果无修饰符,可简化为:
class Person(val name: String, var age: Int)
init 代码块: 主构造函数不能包含逻辑代码,初始化逻辑需放在 init 块中:
class Person(val name: String, var age: Int) {
init {
require(age > 0) { "Age must be positive" }
println("Person initialized: $name, $age")
}
}
2. 次构造函数
次构造函数在类体内定义,使用 constructor 关键字。次构造函数必须委托给主构造函数(直接或间接通过其他次构造函数)。
语法示例:
class Person(val name: String, var age: Int) {
// 次构造函数1:委托给主构造函数
constructor(name: String) : this(name, 0) {
println("Secondary constructor 1 called")
}
// 次构造函数2:委托给次构造函数1
constructor() : this("Anonymous") {
println("Secondary constructor 2 called")
}
}
使用场景:
- 提供多种初始化方式(如默认参数不足时)。
- 兼容 Java 框架(如需要无参构造函数)。
3. 主构造函数 vs 次构造函数
| 特性 | 主构造函数 | 次构造函数 |
|---|---|---|
| 定义位置 | 类头部分 | 类体内部 |
| 参数是否自动成为属性 | 是(若使用 val/var) | 否,需手动赋值 |
| 初始化逻辑 | 通过 init 块 | 直接写在构造函数体内 |
| 委托机制 | 无 | 必须委托给主构造函数或其他次构造函数 |
4. 实际案例
class User(
val id: Int,
val email: String,
var status: String = "inactive"
) {
init {
println("User $id created with email: $email")
}
// 次构造函数:通过邮箱前缀生成ID
constructor(emailPrefix: String) : this(
id = emailPrefix.hashCode(),
email = "$emailPrefix@example.com"
)
}
fun main() {
val user1 = User(1, "alice@example.com") // 主构造函数
val user2 = User("bob") // 次构造函数
}
5. 注意事项
- 如果类有主构造函数,所有次构造函数必须显式委托给它。
- 无主构造函数时,次构造函数可以独立存在(但此时类属性需在
init块或构造函数中初始化)。 - 主构造函数的参数可标记为
val/var直接声明属性,次构造函数的参数不能。
通过合理使用主次构造函数,可以大幅减少样板代码,提高类的可读性和灵活性。
