內部類可以是靜態(static)的,可以使用 public、protected 和 private 訪問控制符,而外部類只能使用 public,或者默認。
成員式內部類
在外部類內部直接定義(不在方法內部或代碼塊內部)的類就是成員式內部類,它可以直接使用外部類的所有變量和方法,即使是 private 的。外部類要想訪問內部類的成員變量和方法,則需要通過內部類的對象來獲取。
請看下面的代碼:
成員式內部類如同外部類的一個普通成員。
成員式內部類可以使用各種修飾符,包括 public、protected、private、static、final 和 abstract,也可以不寫。
若有 static 修飾符,就為類級,否則為對象級。類級可以通過外部類直接訪問,對象級需要先生成外部的對象后才能訪問。
非靜態內部類中不能聲明任何 static 成員。
內部類可以相互調用,例如:
成員式內部類的訪問
內部類的對象以成員變量的方式記錄其所依賴的外層類對象的引用,因而可以找到該外層類對象并訪問其成員。該成員變量是系統自動為非 static 的內部類添加的,名稱約定為“outClassName.this”。
1) 使用內部類中定義的非靜態變量和方法時,要先創建外部類的對象,再由“outObjectName.new”操作符創建內部類的對象,再調用內部類的方法,如下所示:
2) static 內部類相當于其外部類的 static 成員,它的對象與外部類對象間不存在依賴關系,因此可直接創建。示例如下:
運行結果:
size=1
3) 由于內部類可以直接訪問其外部類的成分,因此當內部類與其外部類中存在同名屬性或方法時,也將導致命名沖突。所以在多層調用時要指明,如下所示:
局部內部類
局部內部類(Local class)是定義在代碼塊中的類。它們只在定義它們的代碼塊中是可見的。
局部類有幾個重要特性:
- 僅在定義了它們的代碼塊中是可見的;
- 可以使用定義它們的代碼塊中的任何局部 final 變量;
- 局部類不可以是 static 的,里邊也不能定義 static 成員;
- 局部類不可以用 public、private、protected 修飾,只能使用缺省的;
- 局部類可以是 abstract 的。
請看下面的代碼:
運行結果:
5
123
15
匿名內部類
匿名內部類是局部內部類的一種特殊形式,也就是沒有變量名指向這個類的實例,而且具體的類實現會寫在這個內部類里面。
注意:匿名類必須繼承一個父類或實現一個接口。
不使用匿名內部類來實現抽象方法:
運行結果:
eat something
可以看到,我們用Child繼承了Person類,然后實現了Child的一個實例,將其向上轉型為Person類的引用。但是,如果此處的Child類只使用一次,那么將其編寫為獨立的一個類豈不是很麻煩?
這個時候就引入了匿名內部類。使用匿名內部類實現:
可以看到,匿名類繼承了 Person 類并在大括號中實現了抽象類的方法。
內部類的語法比較復雜,實際開發中也較少用到,本教程不打算進行深入講解,各位讀者也不應該將內部類作為學習JAVA的重點。