Kotlin学习之嵌套类与内部类

    技术2025-07-25  19

    嵌套类

    嵌套类(Nested Class)就是嵌套在另外一个类当中的类,换句话说,我定义一个类,然后在这个类的里面又去定义一个类。在Java里面有内部类的概念。Kotlin和Java这一点是比较类似,但是有一些区别。

    class OutClass { private val str: String = "hello world" class NestedClass { fun nestedMethod() = "welcome" } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main10) OutClass.NestedClass().nestedMethod() }

    这是一个典型的嵌套类的事例。表面上看和Java的内部类挺像的,但是有一些明显的不同。

    内部类

    内部类也是在一个类的里面去定义一个类,但是内部类(Inner Class)需要在类的前面加关键字inner,明确表示这个是个内部类。

    class OutClass2 { private val str: String = "hello world" inner class InnerClass { fun innerMethod() = "welcome" } }

    在内部类里面去访问外部类的成员变量的方式是this@OutClass2.str

    class OutClass2 { private val str: String = "hello world" inner class InnerClass { fun innerMethod() =this@OutClass2.str } }

     调用内部类的innerMethod()

    override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main10) OutClass2().InnerClass().innerMethod() }

    接下来分析下嵌套类和内部类存在怎么的关系,为什么调用方式是不一样的?

    OutClass.NestedClass().nestedMethod() OutClass2().InnerClass().innerMethod()

    回忆一下Java的内部类,是否静态来划分有静态内部类和非静态内部类。但是Kotlin是没有static关键字的,也就是说没有静态属性和静态方法的。那Kotlin如何映射到Java的静态内部类和非静态内部类呢,是通过嵌套类和内部类这样俩种情况进行分别的映射。

    关于嵌套类和内部类之间的区别与联系:

    1.嵌套类:对应于Java的静态内部类(即有static关键字修饰的内部类),只要在一个类的内部定义了另外一个类,那么这个类就叫做嵌套类。相当于Java当中有static关键字修饰的内部类。

    2.内部类:对应于Java中的非静态内部类(即没有static关键字修饰的内部类),使用inner关键字在一个类的内部定义另一个类就叫做内部类。相当于Java当中没有static关键字修饰的内部类。

    这就是为什么嵌套类和内部类调用的方式是不一样的。静态类是可以直接用类名直接去引用,不用去创建对象。

    局部嵌套类

    定义在一个方法里面的一个嵌套类

    class OutClass2 { private val str: String = "hello world" inner class InnerClass { fun innerMethod() = this@OutClass2.str } //局部嵌套类 fun getName(): String { class LocalNestedClass { val name: String = "mytest" } var localNestedClass = LocalNestedClass() return localNestedClass.name } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main10) OutClass2().getName() }

     举一个综合的例子

    class Person(val name: String, var age: Int) { private inner class PersonFeature(var height: Int, var weight: Int) { fun getPersonFeature() { println("身高:$height,体重:$weight") this@Person.method() } } private fun method() { println("执行了Person的method方法") } fun getPerson() { val personFeature = PersonFeature(120, 180) personFeature.getPersonFeature() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main10) val person =Person("zhangsan",20) person.getPerson() }

    内部类PersonFeature会持有外部类Person的引用,所以内部类才能调用外部类的方法,通过 this@Person.method()。

    当外部类 、内部类、方法里面都可以定义成员变量,重名的时候该怎么处理?

    class Person(val name: String, var age: Int) { private val str: String = "Person属性" private inner class PersonFeature(var height: Int, var weight: Int) { private val str: String = "PersonFeature属性" fun getPersonFeature() { val str: String = "局部变量" //1.访问外部类Person的str println("${this@Person.str}") //2.访问当前内部类PersonFeature的str println("${this.str}") //访问局部变量的str println("$str") } } private fun method() { println("执行了Person的method方法") } fun getPerson() { val personFeature = PersonFeature(120, 180) personFeature.getPersonFeature() } }

    访问特定的一个作用域里面的成员变量。

    Kotlin访问外部类变量的方式:this@OutClass.str

    Java访问外部类变量的方式:OutClas.this.str

    再补充一点

    class OutClass { private val str: String = "hello world" class NestedClass { fun nestedMethod() = "welcome" } }

    嵌套类相当于Java中的静态内部类,在Java中静态的只能访问静态的,不能访问非静态的。而非静态的是可以访问非静态和静态的。为什么会有这个规则呢?

    原因是因为静态的并不属于当前类本身,而是属于当前的Class对象。

    在Java中,NestedClass是静态的内部类,str是非静态的成员变量,显然是不能在静态的里面访问非静态的。所以在NestedClass里面是不可能访问到外部类OutClass里面定义的任何成员变量

    那么对于嵌套类来说能访问什么?除了自己类里面定义的成员变量和方法之外,唯一能访问相同的外部类当中所定义的其他的嵌套类,因为他们都是静态的。

    class OutClass { private val str: String = "hello world" class NestedClass { fun nestedMethod() = "welcome" } class NestedClass2 { var nestedClass = NestedClass() } }

     

    Processed: 0.011, SQL: 9