Java 宣告 inner class 的方式,是在 class 中 宣告另一個 class。
Inner class 被編譯後,會產生 outer_class$inner_class 的 classfile。
甚至在 method 中也可以宣告 inner class。
範例:宣告 inner class
class J1 { class J11 { //inner class void print() { System.out.println("J11"); } } }上例會產生兩個 class file
1. J1.class
2. J1$J11.class:代表 J11 的 inner class。
範例:在 method 中宣告 inner class,此時只有該 method 才知道這個 inner class。
class J1 { void p1() { class J11 { //method 中 的 inner class void print() { System.out.println("p1"); } } } void m1() { J11 j11 = new J11();//這裡是錯誤的,因為 m1() 看不到 J11 } }上例會產生兩個 class file
1. J1.class
2. J1$J11.class:代表 J11 的 inner class。
但由於 J11 是宣告在 J1.p1() method 裡面,所以在 m1() 中將看不到 J11 這個 class。
Inner class 的 instance 隱含有一個 outer class instance 的 reference。也就是,若要 create 一個 inner class instance,需要有一個 outer instance 才能成功 create。若在其他 class 要 create inner class 的 instance,需要使用特殊的語法。
範例:inner class instance 的 creation。
class J1 { class J11 { //inner class void print() { System.out.println("J11"); } } void m1() { J11 j11 = new J11();//這裡 create 一個 J11,好像沒有 outer class instance
//但其實在 instance method 中呼叫,已經隱含一個 outer class instance。 } static public void main(String[] args) { J11 j11 = new J11();//這裡會出錯,因為 J11 的 instance 需要 outer class instance J1 j1 = new J1(); J11 j11 = j1.new J11();//這裡使用 j1 來 create J11。
//請注意 j1.new J11() 這個特殊語法 } }
Scala inner class 用法,與 Java 的類似。我們看例子。
範例:宣告 inner class
class S1 { class S11 { def p1 = println("p1") } }上例會產生兩個 class file
1. S1.class
2. S1$S11.class:代表 S11 的 inner class。
請注意,Java 的 inner class 的實際 type,為:outer_class.inner_class,使用「.」dot。
但 Scala 的「.」dot,只能使用在 instance 上。compiler 一遇到 dot 就會試圖解釋為 instance 的 method 或data field。
所以,在 Scala,inner class 的實際 type,為 outer_class#inner_class。Scala 與 Java 不太相同,請注意。
class S1 { class S11 { def p1 = println("p1") } } object Main { def m1 { val s11: S1.S11 = null // 使用 S1.S11 當 type,但這是錯誤的。遇到「S1.xxx」時,compiler 會去找 S1 這個 object val s12: S1#S11 = null // S1#S11 才是正確的 type。 } }範例:在 method 中宣告 inner class,Scala 的用法與 Java 相同。
class S1 { def p1 = { class S11 { // 在 method 中宣告 inner class } } }與 Java 相同,Scala inner class 的 instance,也是隱含一個 outer class 的 reference。所以要 create 一個 inner class 的 instance,需有一個 outer instance。
使用 outer instance 來 create inner instance 的語法,Scala 與 Java 不太相同。
class S1 { class S11 // 這個 class 沒有 body,所以可以省略大括號 } class Main { val s1 = new S val s11 = new s1.S11 // 這裡的語法與 Java 不同,new 為 keyword,放在最前面 }在 Scala 中,不同的 outer instance 所產生出來的 inner instance,type 是不相同的。
讓我們看下一例子。
class S { class Inner; } class Main { val s1 = new S val s1_inner = new s1.Inner //s1_inner 的 type 為 s1.Inner val s2 = new S1 val s2_inner = new S2.inner //s2_inner 的 type 為 s2.inner }上例的 s1_inner 與 s2_inner 都是 S#Inner 的 type。
但實質上,二者的 type 並不相同,一個是 s1.Inner type,另一個是 s2.inner type。這種與 outer instance 相關的 type,稱為 path-dependent type。
沒有留言:
張貼留言