Kotlin学习之嵌套类与内部类

嵌套类

嵌套类(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"
    }
}

在内部类里面去访问外部类的成员变量的方式是[email protected]

class OutClass2 {
    private val str: String = "hello world"

    inner class InnerClass {
        fun innerMethod() [email protected]
    }
}

 调用内部类的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() = [email protected]
    }

    //局部嵌套类
    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")
            [email protected]()
        }
    }

    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的引用,所以内部类才能调用外部类的方法,通过 [email protected]()。

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

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("${[email protected]}")
            //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访问外部类变量的方式:[email protected]

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()
    }

}

猜你喜欢

转载自blog.csdn.net/jingerlovexiaojie/article/details/107124434