在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()中展示的那樣。