前言
Kotlin作為JVM系的語(yǔ)言,起源于Java又不同于Java。通過(guò)在語(yǔ)言層面比較兩者的區(qū)別,可以使得開(kāi)發(fā)者能夠快速學(xué)習(xí),融會(huì)貫通。
概念
在一個(gè)類中定義一個(gè)類就被稱為內(nèi)部類。但是在不同語(yǔ)言中,允許定義的內(nèi)部類種類不同,內(nèi)部類與外部類之間的關(guān)系也略有不同。
內(nèi)部類分類
Java
在Java中共分為四類:靜態(tài)內(nèi)部類:在類中且在方法之外定義的內(nèi)部類,同時(shí)被static修飾。也被稱為嵌套類。
成員內(nèi)部類:在類中且在方法之外被定義的內(nèi)部類,無(wú)static修飾。
局部?jī)?nèi)部類:在類的方法之內(nèi)被定義的內(nèi)部類,無(wú)static修飾
匿名內(nèi)部類:在類中,定義類的同時(shí)對(duì)類進(jìn)行初始化,且沒(méi)有顯式地指明類的名字,故稱為匿名內(nèi)部類
Kotlin
按照Kotlin官網(wǎng)的介紹,其內(nèi)部類共三類:嵌套類:類似于Java的靜態(tài)內(nèi)部類
內(nèi)部類:類似于Java的成員內(nèi)部類
匿名內(nèi)部類:類似于Java的匿名內(nèi)部類
內(nèi)部類示例
- Java
class OuterClass {
...
static class StaticNestedClass { //靜態(tài)內(nèi)部類(嵌套類)
...
}
class InnerClass { //成員內(nèi)部類
...
}
public void someMethod(){
class localClass{ //局部?jī)?nèi)部類
}
}
Object obj = new BaseClass{ //匿名內(nèi)部類
@override
public void someFun(){}
}
}
在Java中,靜態(tài)內(nèi)部類只能訪問(wèn)外部類的靜態(tài)方法或靜態(tài)成員(包括公有或私有的)。成員內(nèi)部類持有對(duì)外部類的引用。局部?jī)?nèi)部類與匿名內(nèi)部類持有對(duì)外部方法的final成員的引用。(是否持有外部類的引用,待做實(shí)驗(yàn))
- Kotlin
嵌套類
Kotlin中默認(rèn)就是嵌套類(Nested Class),不用添加任何修飾符。嵌套類無(wú)法訪問(wèn)外部類的普通成員變量(伴生對(duì)象成員(靜態(tài))除外)。
class Outer {
private val bar: Int = 1
class Nested {
fun foo() = 2
}
}
val demo = Outer.Nested().foo() // == 2
內(nèi)部類,以inner關(guān)鍵字修飾:
class Outer {
private val bar: Int = 1
inner class Inner {
fun foo() = bar
}
}
val demo = Outer().Inner().foo() // == 1
內(nèi)部類與外部類的訪問(wèn)關(guān)系:
class Outer { //外部類
private val text: String = "I like this world"
class Inner { //靜態(tài)內(nèi)部類
private val text: String = "NEW"
fun show() {
// println(this@Outer.text) //此處訪問(wèn)不到
println(this.text) //訪問(wèn)Inner中的text
}
}
inner class Inner2 { //非靜態(tài)內(nèi)部類
private val text: String = "Great"
fun show2() {
println(this.text) //訪問(wèn)Inner2中的text
println(this@Outer.text) //此處的寫(xiě)法相當(dāng)于java中的Outer.this.text
}
}
}
靜態(tài)內(nèi)部類無(wú)法訪問(wèn)外部類普通成員。
給內(nèi)部類加上inner關(guān)鍵詞之后,就會(huì)變成非靜態(tài)內(nèi)部類,可以訪問(wèn)外部類的屬性和方法(包括伴生對(duì)象成員)。
匿名內(nèi)部類,使用對(duì)象表達(dá)式來(lái)使用匿名內(nèi)部類:
window.addMouseListener(object: MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { …… }
override fun mouseEntered(e: MouseEvent) { …… }
})
如果是匿名內(nèi)部類的父類是函數(shù)式接口(FP),則可以使用帶父類接口類型的lambda表達(dá)式創(chuàng)建匿名內(nèi)部類:
val listener = ActionListener { println("clicked") }