在Java 1.1中,可將一個類定義置入另一個類定義中。這就叫作“內部類”。內部類對我們非常有用,因為利用它可對那些邏輯上相互聯系的類進行分組,並可控制一個類在另一個類裡的“可見性”。然而,我們必須認識到內部類與以前講述的“合成”方法存在著根本的區別。
通常,對內部類的需要並不是特別明顯的,至少不會立即感覺到自己需要使用內部類。在本章的末尾,介紹完內部類的所有語法之後,大家會發現一個特別的例子。通過它應該可以清晰地認識到內部類的好處。
創建內部類的過程是平淡無奇的:將類定義置入一個用於封裝它的類內部(若執行這個程序遇到麻煩,請參見第3章的3.1.2小節“賦值”):
//: Parcel1.java // Creating inner classes package c07.parcel1; public class Parcel1 { class Contents { private int i = 11; public int value() { return i; } } class Destination { private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } } // Using inner classes looks just like // using any other class, within Parcel1: public void ship(String dest) { Contents c = new Contents(); Destination d = new Destination(dest); } public static void main(String[] args) { Parcel1 p = new Parcel1(); p.ship("Tanzania"); } } ///:~
若在ship()內部使用,內部類的使用看起來和其他任何類都沒什麼分別。在這裡,唯一明顯的區別就是它的名字嵌套在Parcel1裡面。但大家不久就會知道,這其實並非唯一的區別。
更典型的一種情況是,一個外部類擁有一個特殊的方法,它會返回指向一個內部類的句柄。就象下面這樣:
//: Parcel2.java // Returning a handle to an inner class package c07.parcel2; public class Parcel2 { class Contents { private int i = 11; public int value() { return i; } } class Destination { private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } } public Destination to(String s) { return new Destination(s); } public Contents cont() { return new Contents(); } public void ship(String dest) { Contents c = cont(); Destination d = to(dest); } public static void main(String[] args) { Parcel2 p = new Parcel2(); p.ship("Tanzania"); Parcel2 q = new Parcel2(); // Defining handles to inner classes: Parcel2.Contents c = q.cont(); Parcel2.Destination d = q.to("Borneo"); } } ///:~
若想在除外部類非static方法內部之外的任何地方生成內部類的一個對象,必須將那個對象的類型設為“外部類名.內部類名”,就象main()中展示的那樣。