类、属性与接口
Kotlin 的类系统极度精简。它通过主构造函数、属性代理和默认 final 等特性,强制引导开发者编写更安全的代码。
构造体系
Kotlin 区分 主构造函数 (Primary) 与 次构造函数 (Secondary)。
kotlin
// 1. 直接在类头定义参数
// 2. var/val 参数自动成为属性
class User(val id: Int, var name: String) {
// 初始化块 (Init Block):配合主构造函数使用
init {
require(id > 0) { "Invalid ID" }
println("User $name created")
}
}kotlin
class View : View {
// 必须委托给主构造函数 (如果存在) 或其他次构造函数
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}属性 (Properties)
Kotlin 的属性不仅仅是字段,它自带 Getter/Setter 钩子。
幕后字段 (Backing Field)
当你自定义 Setter 时,必须使用 field 关键字来访问实际存储值的变量。
kotlin
var counter = 0
set(value) {
if (value >= 0) {
// ❌ counter = value (死循环!)
field = value // ✅ 正确
}
}继承与多态
默认 Final
Kotlin 类默认是 final 的(不可继承)。要允许继承,必须添加 open 关键字。
kotlin
open class Base {
open fun v() {}
fun nv() {} // 默认为 final,不可覆盖
}
class Derived : Base() {
override fun v() {}
}super 歧义处理
当继承的多个父类(如接口)有同名默认实现时,必须显式指定 super<T>。
kotlin
interface A { fun foo() = print("A") }
interface B { fun foo() = print("B") }
class C : A, B {
override fun foo() {
super<A>.foo() // 调用 A.foo()
super<B>.foo() // 调用 B.foo()
}
}嵌套类 vs 内部类
这是 Android 开发中 内存泄漏 的高发区。
| 关键字 | 对应 Java | 持有外部引用? | 风险 |
|---|---|---|---|
| 无 (默认) | static class | 否 | 安全 |
inner | class | 是 | 高风险 (可能导致 Activity 泄漏) |
内存泄漏警告
在 Activity/Fragment 中使用 inner class (如 Handler, Adapter) 时,如果该内部类的生命周期长于外部类(例如被异步线程持有),会导致 Activity 无法被 GC 回收。 建议:默认使用嵌套类(不加 inner)。
kotlin
class Outer {
private val bar: Int = 1
// 嵌套类:无法访问 bar
class Nested {
fun foo() = 2
}
// 内部类:可以访问 bar
inner class Inner {
fun foo() = bar
}
}函数式接口 (Functional Interface)
如果接口只有一个抽象方法,标记为 fun interface 可支持 SAM 转换(直接传入 Lambda)。
kotlin
fun interface ClickListener {
fun onClick(pos: Int)
}
// 使用
val listener = ClickListener { pos -> println("Clicked $pos") }