提起Java內部類(Inner Class)可能很多人不太熟悉,實際上類似的概念在C++裏也有,那就是嵌套類(Nested Class),關於這兩者的區別與聯繫,在下文中會有對比。內部類從表面上看,就是在類中又定義了一個類(下文會看到,內部類可以在很多地方定義),而實際上並沒有那麼簡單,乍看上去內部類似乎有些多餘,它的用處對於初學者來說可能並不是那麼顯著,但是隨着對它的深入瞭解,你會發現Java的設計者在內部類身上的確是用心良苦。學會使用內部類,是掌握Java高級編程的一部分,它可以讓你更優雅地設計你的程序結構。下面從以下幾個方面來介紹:
第一次見面
public interface Contents { int value(); }
public interface Destination { String readLabel(); }
public class Goods { private class Content implements Contents { private int i = 11; public int value() { return i; } }
protected class GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } }
public Destination dest(String s) { return new GDestination(s); } public Contents cont() { return new Content(); } }
class TestGoods { public static void main(String[] args) { Goods p = new Goods(); Contents c = p.cont(); Destination d = p.dest("Beijing"); } }
在這個例子裏類Content和GDestination被定義在了類Goods內部,並且分別有着protected和private修飾符來控制訪問級別。Content代表着Goods的內容,而GDestination代表着Goods的目的地。它們分別實現了兩個接口Content和Destination。在後面的main方法裏,直接用 Contents c和Destination d進行操作,你甚至連這兩個內部類的名字都沒有看見!這樣,內部類的第一個好處就體現出來了——隱藏你不想讓別人知道的操作,也即封裝性。
同時,我們也發現了在外部類作用範圍之外得到內部類對象的第一個方法,那就是利用其外部類的方法創建並返回。上例中的cont()和dest()方法就是這麼做的。那麼還有沒有別的方法呢?當然有,其語法格式如下:
outerObject=new outerClass(Constructor Parameters);
outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);
注意在創建非靜態內部類對象時,一定要先創建起相應的外部類對象。至於原因,也就引出了我們下一個話題——非靜態內部類對象有着指向其外部類對象的引用,對剛纔的例子稍作修改:
public class Goods {
private valueRate=2;
private class Content implements Contents { private int i = 11*valueRate; public int value() { return i; } }
protected class GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } }
public Destination dest(String s) { return new GDestination(s); } public Contents cont() { return new Content(); } }
修改的部分用藍色顯示了。在這裏我們給Goods類增加了一個private成員變量valueRate,意義是貨物的價值係數,在內部類Content的方法value()計算價值時把它乘上。我們發現,value()可以訪問valueRate,這也是內部類的第二個好處——一個內部類對象可以訪問創建它的外部類對象的內容,甚至包括私有變量!這是一個非常有用的特性,爲我們在設計時提供了更多的思路和捷徑。要想實現這個功能,內部類對象就必須有指向外部類對象的引用。Java編譯器在創建內部類對象時,隱式的把其外部類對象的引用也傳了進去並一直保存着。這樣就使得內部類對象始終可以訪問其外部類對象,同時這也是爲什麼在外部類作用範圍之外向要創建內部類對象必須先創建其外部類對象的原因。
|
|