Kotlin面向对象 (7)✔️嵌套类

2019-05-30  本文已影响0人  狼性代码人
  • 嵌套类
  • 内部类 (特殊的嵌套类)

个人理解:kotlin嵌套类可以理解为 Java 中的静态内部类,嵌套类不持有外部类引用;而 kotlin 中的内部类也可以理解为 Java 中的非静态内部类,内部类持有外部类的引用。

一、嵌套类

嵌套类可以声明为 publicprotectedinternalprivate

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️⃣行,需要先实例化外部类,再通过这个实例化的外部类来创建内部类。

上一篇下一篇

猜你喜欢

热点阅读