Kotlin-嵌套类_内部类_匿名内部类

发布时间 2023-11-03 18:07:27作者: 夜行过客

Kotlin-嵌套类&内部类&匿名内部类

1. 嵌套类

类可以被嵌套在其它类中:

class Outer {
    private val bar: Int = 1

    class Nested {
        fun foo() {
            println("foo in Outer#Nested#foo() ")
        }

        fun test() {
            // println("Nested: bar value: $bar") // 报错:Unresolved reference: bar
        }
    }
}


fun main() {
    Outer.Nested().foo()
}

运行:

foo in Outer#Nested#foo() 

注意:嵌套类不能访问外部类的成员变量,方法test()是无法执行的,编译器会报错:Unresolved reference: bar

您还可以使用带有嵌套的接口。类和接口的所有组合都是可能的:您可以在类中嵌套接口、在接口中嵌套类、以及在接口中嵌套接口。

interface OuterInterface {
    class InnerClass
    interface InnerInterface
}

class OuterClass {
    class InnerClass
    interface InnerInterface
}

上述语法结构在kotlin中都是允许的。

2. 内部类 inner class

class Outer {
    private val bar: Int = 1

    class Nested {
        fun foo() {
            println("foo in Outer#Nested#foo() ")
        }

        fun test() {
            // println("Nested: bar value: $bar") // 报错:Unresolved reference: bar
        }
    }

    inner class Inner {
        fun foo() {
            println("foo in Outer#Inner#foo() ")
        }

        fun test() {
            println("Inner: bar value: $bar")
        }

        fun test2() {
            val outer = this@Outer // 获取外部类的引用
            println("outer: $outer")
        }
    }
}


fun main() {
    Outer.Nested().foo()
    Outer().Inner().foo()
    Outer().Inner().test()
    Outer().Inner().test2()
}

运行:

foo in Outer#Nested#foo() 
foo in Outer#Inner#foo() 
Inner: bar value: 1
outer: com.yongdaimi.kotlin.Outer@2503dbd3

kotlin中的内部类使用 inner class 关键字来修饰,内部类是可以访问外部类的成员的(包括成员函数和成员属性),如 Outer().Inner().test()方法,且内部类也可以获取外部类的引用,使用 this@外部类名的语法,

注意:调用内部类方法时,不能使用 Outer.Inner().foo()的语法:

image-20231103175101085

外部类必须加上括号。

3. 匿名内部类

匿名内部类使用object 表达式创建,即:object: 类名()的形式:

package com.yongdaimi.kotlin

class Outer {
    private val bar: Int = 1

    class Nested {
        fun foo() {
            println("foo in Outer#Nested#foo() ")
        }

        fun test() {
            // println("Nested: bar value: $bar") // 报错:Unresolved reference: bar
        }
    }

    inner class Inner {
        fun foo() {
            println("foo in Outer#Inner#foo() ")
        }

        fun test() {
            println("Inner: bar value: $bar")
        }

        fun test2() {
            val outer = this@Outer // 获取外部类的引用
            println("outer: $outer")
        }
    }

    abstract class BaseAdapter {
        abstract fun getPosition(position: Int)
    }

    fun setAdapter(adapter: BaseAdapter) {

    }
}


fun main() {
    Outer.Nested().foo()
    Outer().Inner().foo()
    Outer().Inner().test()
    Outer().Inner().test2()

    val outer = Outer()
    outer.setAdapter(object : Outer.BaseAdapter() {
        override fun getPosition(position: Int) {

        }
    })
}

上文的 object : Outer.BaseAdapter() 就是一个匿名内部类。