內部類簡單介紹
內部類就是在一個類中再定義一個類,內部類可以起到包裝隱藏的作用,不允許同一包中的其他類來訪問該類,內部類的方法可以訪問所以外部類的資料。Think in Java中:每個內部類都能獨立的繼承一個介面的實現,所以無論外部類是否已經繼承了某個介面的實現,對內部類是沒有影響的。
【1】成員內部類
【2】靜態內部類
【3】區域性內部類
【4】匿名內部類
成員內部類
成員內部類也是最為普通的內部類,他是外部類的一個成員,所以可以無限制的訪問外部類中是所以變數和方法,但是外部類訪問內部類必須通過內部類的例項也就是物件才能訪問。成員內部類不能訪問任何的static變數和方法。
<span style="font-size:18px;">package OneWeek; public class OrdOuter { private String name = "zhangsan"; private int age = 999; private int score = 10000; public String getNameAge(){ return "姓名:"+this.name+" 年齡:"+this.age; } public class Inner{ private int score = 100; public void test(){ System.out.println("內部類訪問外部類的name:"+name); System.out.println("內部類訪問外部類的age:"+age); System.out.println("訪問內部類的score:"+score); System.out.println("訪問外部類的score:"+OrdOuter.this.score); } } public static void main(String args[]){ OrdOuter out = new OrdOuter(); Inner in = out.new Inner(); System.out.println(out.getNameAge()); in.test(); } }</span>
靜態內部類
前面提到static可以修飾成員變數、方法、程式碼塊,他還可以修飾內部類,我們稱之為靜態內部類。靜態內部類和普通的成員內部類是不同的,普通的成員內部類在編譯之後會隱含儲存著一個指向外部類的引用,而靜態內部類是沒有的,也就是說他的建立不需要依賴外部類,他不能使用任何外部類中的非靜態變數和方法。
<span style="font-size:18px;">package OneWeek; public class StaOuter { private static String name = "zhangsan"; private static int age = 999; private static int score = 10000; public static String getNameAge(){ return "姓名:"+name+" 年齡:"+age; } public static class Inner{ private static int score = 100; public void test(){ System.out.println("內部類訪問外部類的name:"+name); System.out.println("內部類訪問內部類的score:"+Inner.score);//訪問相同的變數時要加類名 System.out.println("內部類訪問外部類的score:"+StaOuter.score); } } public static void main(String args[]){ Inner in = new Inner(); //System.out.println(in.getNameAge());//不能直接訪問外部類中的靜態方法 in.test(); } }</span>
區域性內部類
區域性內部類也叫方法內部類,其實就是將內部類定義在方法之中,限制了其有效範圍,方法內部類只在方法的內部可見,也就是隻能再該方法中使用。
<span style="font-size:18px;">package OneWeek; public class MetOuter { private String name = "張三"; private int age = 666; public String getNameAge(){ return "姓名:"+name+" 年齡:"+age; } public void show(){ class Inner{ private String name = "李四"; private int age = 999; public String getNameAge(){ return "姓名:"+name+" 年齡:"+age; } } Inner in = new Inner();//只能在該方法中呼叫該類 System.out.println(in.getNameAge()); } public static void main(String args[]){ MetOuter out = new MetOuter(); out.show();// 呼叫的也是內部類中的變數 } }</span>
匿名內部類
匿名內部類必須繼承一個父類或者實現一個介面,同時其沒有class關鍵字,是通過new來生成一個物件的引用。匿名類中不能定義建構函式,匿名類中不能有static變數和方法,匿名內部類不能是抽象的,他必須實現繼承的類或者是實現介面的所有抽象方法。
<span style="font-size:18px;">package OneWeek;
public class OutClass {
public InnerClass1 getInnerClass(final int num){//外部類中的方法
return new InnerClass1(){//匿名內部類的建立
int n = num*6;
public int getNumber(){//實現抽象類中的方法,或者是介面中的方法
return n;
}
};
}
abstract class InnerClass1{//需要實現的抽象類或者介面
abstract int getNumber();
}
public static void main(String args[]){
OutClass out = new OutClass();
InnerClass1 inner = out.getInnerClass(2); //直接呼叫方法
System.out.println(inner.getNumber());
}
}</span>
匿名內部類通過new 的方式來建立,只不過上面的例子是將new 的建立和外部類方法的返回相結合了。
我們給匿名內部類傳遞的引數也是final型別,其目的是保證引數的一致性,內部類的屬性和外部類方法的引數時不相同的,外部看起來一樣但卻是可以獨立變換的,如上邊例子中的fianl int num,外部類方法中的引數num傳遞給了內部類中的n,為了保證這兩個的一致性,必須使用final。