- 嵌套类
- 内部类 (特殊的嵌套类)
- kotlin 语言中允许在一个类的内部声明另一个类,称为“嵌套类”,嵌套类还有一种特殊形式——内部类。
个人理解:kotlin嵌套类可以理解为 Java 中的静态内部类,嵌套类不持有外部类引用;而 kotlin 中的内部类也可以理解为 Java 中的非静态内部类,内部类持有外部类的引用。
一、嵌套类
嵌套类可以声明为 public、protected、internal 和 private。
class View { // 外部类
val width: Int = 20
class Button { // 嵌套类
fun onClick() {
println("onClick...")
// println(width) // 编译错误 1️⃣
}
}
fun test() {
val button = Button()
button.onClick()
}
}
上面第1️⃣行代码,尝试访问外部类的属性 width 编译错误,因为嵌套类 Button 并不持有外部类 View 的引用,自然也不能访问外部类的属性。
fun main(args: Array<String>) {
val button = View.Button() // 2️⃣
button.onClick()
val view = View()
view.test()
}
代码第2️⃣行可以看出,嵌套类 Button 可以通过外部类点 (View.) 嵌套类名 (Button) 单独构造 (外部类 view
并未创建)。
二、内部类 (特殊的嵌套类)
内部类是一种特殊的嵌套类,内部类可以访问外部类属性、函数,因为内部类持有外部类引用。内部类的声明需要在 class 前面加 inner 关键字。
class Outer { // 外部类
val x = 10
fun printOuter() {
println("调用外部函数...")
}
fun test() {
val inner = Inner()
inner.display()
}
inner class Inner { // 内部类
private val x = 20
fun display() {
println("外部类属性 x = ${this@Outer.x}") // 4️⃣
println("内部类属性 x = ${this.x}") // 3️⃣
println("内部类属性 x = ${x}")
this@Outer.printOuter()
printOuter() // 5️⃣
}
}
}
提示:在内部类中 this 是引用当前内部类对象,见代码第3️⃣行。而要引用外部类对象需要使用 this@类名,见代码第4️⃣行,如果内部类和外部类的成员命名没有冲突,在引用外部类成员时可以不用加 this@类名,见代码第5️⃣行。
fun main(args: Array<String>) {
val outer = Outer()
outer.test()
// val inner1 = Outer.Inner() // 编译错误
val inner1 = Outer().Inner() // 6️⃣ 必需通过实例Outer来创建Inner类
inner1.display()
}
一般情况下,内部类不能为外部类之外调用,只是为外部类使用的。但如果一定要在外部类之外访问内部类,kotlin也是支持的,见代码第6️⃣行,需要先实例化外部类,再通过这个实例化的外部类来创建内部类。
网友评论