多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 嵌套类/内部类 [TOC] 我们在Kotlin内部还可以定义类,这样的类,我们可以称为嵌套类(nestedclasses)。**嵌套类分成两种类型,一种是不通过Inner关键字修饰的嵌套类,一种是通过Inner关键字修饰的嵌套类(也称为内部类)**。两者的**区别主要体现在类的创建以及对外部内属性的访问上**。 Kotlin中的**嵌套类是指可以嵌套在其他类中的类,该类不能访问外部类的成员,内部类指的是可以用inner标记以便能够访问外部类的成员**。Kotlin中的内部类与嵌套类与Java中的类似,不同的是在没有任何修饰的情况下,定义在一个类内部的类被默认称为嵌套类,不持有外部类的引用,如果想将它声明为一个内部类,则需要加上inner修饰符。 ### **嵌套类** 我们先看**不通过Inner关键字修饰的嵌套类,这样的嵌套类,不能访问外部类的成员属性,这样的嵌套类,在创建的时候,不需要先创建外部类对象**。参考代码: ![](http://upload-images.jianshu.io/upload_images/7368752-791c1baa7c48e6ec.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 针对以上代码我们看第11行**创建嵌套类对象的时候,不用先创建外部类对象。同时,嵌套类不能访问外部类成员属性**,参考代码: ![](http://upload-images.jianshu.io/upload_images/7368752-6d9367ee28d98c85.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 示例: ~~~ class Outer { var outerVal = 10 fun myFun() { println("outer") } class Nested { //嵌套类不能访问外部类成员,相当于java的static 静态内部类 fun myFun(): Unit { println("Nested") } } } fun main(args: Array<String>) { //创建嵌套类Nest对象,不需要外部类Outer对象 val nested = Outer.Nested() nested.myFun() } ~~~ 运行结果 ``` Nested Process finished with exit code 0 ``` ### **内部类** 通过上一小节的学习,我们会发现在嵌套类中是无法访问外部类中成员的,这样定义的嵌套类在实际开发中没有任何意义,为此,Kotlin中提供了内部类,内部类只需要在嵌套类的基础上添加一个“inner”关键字即可,将其标识为内部类。 我们再看通过Inner关键字修饰的嵌套类,这样的嵌套类(内部类),**能访问外部类的成员属性**,这样的嵌套类,**在创建的时候,需要先创建外部类对象**。参考代码: ![](http://upload-images.jianshu.io/upload_images/7368752-679f1af03d714cab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 示例 ~~~ class Outer1 { private var outerVal = 10 fun myFun() { println("outer") } //内部类可以访问外部类成员,可看作外部类对象的一个成员(即便是private) inner class Inner { fun myFun(): Unit { println("Inner" + "可以访问到的外部类的私有成员outerVal:${outerVal}") } } } fun main(args: Array<String>) { var outer = Outer1(); var inner = outer.Inner();//创建内部类Inner对象,需要外部类Outer对象 //var inner1 = Outer.Inner();//这里会报错 //调用方法 outer.myFun() inner.myFun() } ~~~ 运行结果 ``` outer Inner可以访问到的外部类的私有成员outerVal:10 Process finished with exit code 0 ``` ### **匿名内部类** 用[对象表达式](https://www.kancloud.cn/alex_wsc/android_kotlin/1318311),创建匿名内部类的实例: ~~~ window.addMouseListener( object: MouseAdapter() { override fun mouseClicked(e: MouseEvent) { ... } override fun mouseEntered(e: MouseEvent){ ... } } ) ~~~ >[success]**注**:对于 JVM 平台, 如果对象是函数式 Java 接口(即具有单个抽象方法的 Java 接口)的实例, 你可以使用带接口类型前缀的lambda表达式创建它。 当接口仅有一个接口方法/函数,可用lambda表达式省略接口方法/函数: ~~~ val listener = ActionListener{ println("clicked") //lambda表达式-简化的匿名内部类 } ~~~ **参考**: * [创建匿名类对象](https://www.kancloud.cn/alex_wsc/android_kotlin/1037838#_20) * [匿名内部类](https://www.kancloud.cn/alex_wsc/android_kotlin/1318309#_26) ### Java中的嵌套类和内部类与Kotlin中的区别 * (1)在Java中,将一个类定义在另一个类的内部,则称这个类为成员内部类,如果成员内部类加上static修饰,则是称为静态内部类。Java中成员内部类中可以访问外部类的所有成员。 * (2)在Kotlin中,将一个类定义在另一个类的内部,不加任何修饰符,则这个类将被默认为是一个嵌套类,如果加上inner修饰,则是一个内部类。Kotlin中的内部类可以访问外部类中的变量,而嵌套类却不可以访问。