一、內部類介紹
內部類:將一個類的定義放在另一個類的定義內部。
內部類是個編譯時的概念,一旦編譯成功后,它就與外圍類屬于兩個完全不同的類(當然他們之間還是有聯系的)。對于一個名為OuterClass的外圍類和一個名為InnerClass的內部類,在編譯成功后,會出現這樣兩個class文件:OuterClass.class和OuterClass$InnerClass.class。
內部類的作用
1.內部類可以很好的實現隱藏,一般的非內部類,是不允許有 private 與protected權限的,但內部類可以。
2.內部類擁有外圍類的所有元素的訪問權限。
3.每個內部類都能獨立繼承自一個(接口的)實現,所以無論外圍類是否已經繼承了某個(接口的)實現,對于內部類都沒有影響。也就是實現多重繼承。
4.可以避免修改接口而實現同一個類中兩種同名方法的調用。
二、四大內部類詳解
1、成員內部類
定義:定義在另一個類(外部類)的內部,而且與成員方法和屬性平級叫成員內部類。
案例如下:
public class MembersOuter {
private int count;
private Inner inner;
public MembersOuter() {
this.inner = new Inner();
}
/**
* 計數
*/
public int count(){
count = inner.num;
return count;
}
public void culcater(){
count ++;
}
public class Inner{
public int num = 2;
public int innerCount(){
culcater();
return count++;
}
public int innerCount2(){
return ++count;
}
}
public static void main(String[] args) {
MembersOuter out = new MembersOuter();
MembersOuter.Inner inner1 = new MembersOuter().new Inner();//創建內部類實例
MembersOuter.Inner inner2 = out.new Inner(); //創建內部類實例
System.out.println(out.count());
System.out.println(out.inner.innerCount());
System.out.println(out.inner.innerCount2());
}
}
案例輸出結果:
2
2
4
要點:
- 成員內部類中不能存在static關鍵字,即,不能聲明靜態屬性、靜態方法、靜態代碼塊等。
【非靜態內部類也可以定義靜態成員同時需要有final關鍵詞修飾,靜態方法鑒于無法用final修飾,仍必須是在靜態內部類 或者非內部類中定義。】 - 創建成員內部類的實例使用:外部類名.內部類名 實例名 = 外部類實例名.new 內部類構造方法(參數)。
可以理解為隱式地保存了一個引用,指向創建它的外部類對象。 - 在成員內部類中訪問外部類的成員方法和屬性時使用:外部類名.this.成員方法/屬性。也可直接調用。
- 內部類在編譯之后生成一個單獨的class文件,里面包含該類的定義,所以內部類中定義的方法和變量可以跟父類的方法和變量相同。
例如上面定義的三個類的class文件分別是:MembersOuterClass .classs和MembersOuterClass $InnerClass.class三個文件。 - 外部類無法直接訪問成員內部類的方法和屬性,需要通過內部類的一個實例來訪問。
- 與外部類平級的類繼承內部類時,其構造方法中需要傳入父類的實例對象。且在構造方法的第一句調用“外部類實例名.super(內部類參數)”。
2、靜態內部類
定義:使用static修飾的成員內部類叫靜態內部類。
案例如下:
案例輸出結果:
要點
1、靜態內部類可以有靜態成員和靜態方法。
2、靜態內部類不可以訪問外部類非靜態的屬性和方法。
3、外部類訪問靜態內部類需要通過內部類的一個實例來訪問。
4、實例創建不需要通過外部類引用。
3、局部內部類
定義:定義在代碼塊、方法體內、作用域(使用花括號“{}”括起來的一段代碼)內的類叫局部內部類。
要點
1. 局部內部類只能在代碼代碼塊、方法體內和作用域中使用(如創建對象和使用類對象等)
2. 局部內部類訪問作用域內的局部變量,該局部變量需要使用final修飾。
3. 可以使用abstract修飾,聲明為抽象類。
4、匿名內部類
定義:匿名內部類沒有名字,而且只能使用一次,創建實例后,類定義會立即消失。
要點
1、使用匿名內部類時,我們必須是繼承一個類或者實現一個接口,但是兩者不可兼得,同時也只能繼承一個類或者實現一個接口。
2、匿名內部類中是不能定義構造函數的。
3、匿名內部類中不能存在任何的靜態成員變量和靜態方法。
4、匿名內部類為局部內部類,所以局部內部類的所有限制同樣對匿名內部類生效。
5、匿名內部類不能是抽象的,它必須要實現繼承的類或者實現的接口的所有抽象方法。