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

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章