Kotlin笔记(八)——内部类和匿名类

来源:互联网 发布:淘宝的游戏藏宝湾 编辑:程序博客网 时间:2024/06/14 12:59

Kotlin可以定义内部类,内部类就是定义在一个类内部的类,一般说明这个类在一定程度上依附于外部类,这种依附体现在两个方面:一方面是逻辑上的依附,另一方面是数据上的依附,内部类持有一个外部类对象的引用。

class OuterClass {    private val aPrivateProp: Int = 0    val aPublicProp: Int = 0    private fun aPrivateFunc() = println("private")    fun aPublicFunc() = println("public")    inner class InnerClass {        fun useOuterProp() {            println("prop:$aPrivateProp")            println("prop:$aPublicProp")            println("prop:${this@OuterClass.aPrivateProp}")            println("prop:${this@OuterClass.aPublicProp}")        }        fun useOuterFunc() {            aPrivateFunc()            aPublicFunc()            this@OuterClass.aPrivateFunc()            this@OuterClass.aPublicFunc()        }    }}

上面的例子中定义了一个外部类OuterClass和一个内部类InnerClass,内部类有两种方式可以使用外部类的所有属性和方法,一种是直接使用属性和方法,一种是使用this引用访问,之前的文章有说过,this引用代表了一个对象本身,Kotlin默认为函数,方法等元素分配了一个label,一般是该元素的名称,引用这个label可以使用@label,由于内部类持有一个外部类的引用,我们可以使用this@OuterClass来引用保存在内部类中的外部类tthis引用。如果要使用内部类,如下所示:

val inner = OuterClass().InnerClass()inner.useOuterProp()inner.useOuterFunc()

我们在OuterClass定义另一个类,差别在于我们去掉了inner关键字。

class AnotherInnerClass(val outer: OuterClass) {    fun useOuterProp() {        println("prop:$outer.aPrivateProp")        println("prop:$outer.aPublicProp")        println("prop:${outer.aPrivateProp}")        println("prop:${outer.aPublicProp}")    }    fun useOuterFunc() {        outer.aPrivateFunc()        outer.aPublicFunc()        outer.aPrivateFunc()        outer.aPublicFunc()    }}

此时我们无法直接访问外部类的属性和方法了,但是我们可以如例子中定义类,这样的类没有外部类对象的引用,所以无法直接访问到外部类的属性和方法,但是我们通过构造函数传入一个外部类的对象,就可以访问外部类所有的属性和方法了,与单独定义一个类不同,这样的类虽然使用了外部类的引用,但是能够访问到外部类的私有方法和属性,而单独定义的类是做不到的。看一下如何使用这个类:

val anotherInner = OuterClass.AnotherInnerClass(OuterClass())anotherInner.useOuterProp()anotherInner.useOuterFunc()

注意与上面的使用方法进行区分,这里不再赘述。


下面看一下匿名类。有些时候我们定义一个类,可能只是为了实现一个接口(interface没有方法的实现)或者派生自一个类,而实际上我们只需要使用这个类的对象一次,例如Android开发中的Listener。那么我们完全没有必要大费周章去为这一个对象定义一个类,我们可以使用匿名类这个简单的语法。看一个例子:

class AnonymousClass {    interface OnClickedListener {        fun onClicked()    }    private var mListener: OnClickedListener? = null    fun setOnClickedListener(listener: OnClickedListener) {        mListener = listener    }    fun click() {        mListener?.onClicked()    }}

我们定义了一个类,这个类中定义了一个接口OnClickedListener,这个类的click方法会调用通过setOnCLickedListener设置的listener。这里没有出现匿名类的踪迹,别急,看看使用这个类的main函数:

fun main(args: Array<String>) {    val ac = AnonymousClass()    ac.setOnClickedListener(object : AnonymousClass.OnClickedListener {        override fun onClicked() {            println("Clicked!")        }    })    ac.click()}

匿名类使用object定义,上面我们定义了一个实现了OnClickedListener接口的匿名类,并创建了一个这个匿名类的对象,将其赋值给了ac


原创粉丝点击