昨天介紹了內部類的作用,及局部內部類今天的主角就是....
把一個類別放在另一個類別內,屬於類別成員,因為屬於其外部類別的成員,所以可以用private、protected 、static修飾
public class OuterClass{
//此處可以定義內部類別
}
public class Test01 {
public static void main(String[] args) {
//建立物件:先有外再有內
Outer01.Inner01 i01 = new Outer01().new Inner01();
i01.show();
Outer01 o01 = new Outer01();
o01.get();
Outer01.AA aa = Outer01.AA.左;
}
}
//------------------
class Outer01{
int a = 200;
void get() {
int c2 = 1;
System.out.println("方法內區域變數:"+c2);
System.out.println("本類的成員變數:"+this.a);
System.out.println("內部類成員變數:"+new Inner01().b);
}
class Inner01{//一般內部類
int b = 99;
void show() {
int b2 = 99999;
System.out.println("方法內區域變數:"+b2);
System.out.println("本類的成員變數:"+this.b);
System.out.println("外部類成員變數:"+Outer01.this.a);
}
}
enum AA{
左,右;
}
abstract class BB{}
interface CC{}
class DD extends BB implements CC{}
}
編譯上面的程式,可以發現一般內部類的class檔命名會以這種形式:
OuterClass$InnerClass.class
為什麼一般內部類可以直接存取其外部類別的private 實例變數?
因為一般內部類別物件裡存放了一個寄生的外部類別物件參照
記憶體配置:
存取變數的順序:
方法內
->內部類別
->外部類别
當在非靜態內部類別的方法内存取某個變數時,系統優先在該方法內
尋找是否存在該名字的局部變數,如果存在就使用該變數;如果不存在,則到該方法所在的內部類別
中尋找是否存在該名字的成員變數,如果存在則使用該成員變數;如果不存在,則到該内部類別所在的外部類别
中尋找是否存在該名字的成員變數,如果存在則使用該成員變數;如果依然不存在,系統將出現編譯錯誤:提示找不到該變數
如果外部類別成員變數、內部類別成員變數與內部類別裡方法的局部變數同名,則可通過使用this.變數名
、外部類別的類别名稱.this.變數名
作為限定來區分
如:this.b、Outer01.this.a
外部類別要存取內部類變數要先建立內部類物件
如:new Inner01().b
非靜態內部類與外部類的關係:
一般內部類別物件必須寄生在外部類別物件裡,而外部類别物件則不必一定有內部類別物件寄生其中。如果存在一個非靜態內部類別物件,則一定存在一個被它寄生的外部類別物件。但外部類別物件存在時,外部類別物件裡不一定寄生了非靜態內部類別物件。因此外部類別物件存取非靜態內部類別成員時,可能非靜態普通內部類別物件根本不存在!而非靜態內部類別物件存取外部類別成員時,外部類别物件一定存在。
根據靜態成員不能存取非靜態成員的規則,外部類别的靜態方法、靜態程式碼區塊不能存取非靜態內部類別,包括不能使用非靜態內部類別定義變數、建立實例等。
總之,不允許在外部類別的靜態成員中直接使用非靜態內部類别
也不允許在一般內部類定義靜態成員,如:靜態方法、靜態成員變數、靜態初始化區塊
注意:
存取權限為private時,只有本類別可以讀取。
內部類也擁有建構子。
今天就到這邊嚕!!!