內部類詳解學習筆記
OK,先來看下內部類的定義是什麼?顧名思義啊,內部類就是一個定義在類或者方法裡面的類,像寄生蟲一樣,就像:
class C{
class D{
.......
}
}
上面的類D就是屬於一個內部類,而類C相對而言就是一個外部類。
然而,內部類還分為四種:成員內部類、區域性內部類、匿名內部類、靜態內部類。
(對於分類這個東西,常常是會忘掉的,但是呢,我有強迫症,所以我想把它們的分類給記住,所以我編個四字成語 “橙橘逆境”(成局匿靜)玩個諧音來加強記憶,橙子橘子在內部遭遇著逆境。)
成員內部類
成員內部類,定義在另一個類中。OK,那麼成員內部類有什麼特點呢?
成員內部類可以無條件訪問外部類的屬性和方法
class C{ private String name = "外部類的屬性"; public void run(){ System.out.println("外部類的方法"); } class D{ public void say(){ System.out.println(name); run(); } } }
但是外部類想要訪問內部類的屬性和方法就必須要,先建立一個內部類物件,通過物件去訪問內部類的屬性和方法。
class C{ privateString name = "外部類的屬性"; public void run(){ System.out.println("外部類的方法"); } /*使用內部類的屬性和方法*/ public void eat(){ D d = new D(); System.out.println(d.value); d.say(); } class D{ private String value = "內部類屬性"; public void say(){ System.out.println(name); run(); } } }
如果成員內部類的屬性或者方法與外部類的同名,將導致外部類的這些屬性與方法在內部類被隱藏,也可按照該格式呼叫,外部類.this.屬性/方法。
class C{ private String name = "外部類"; public void run(){ System.out.println("外部類奔跑"); } /*使用內部類的屬性和方法*/ public void eat(){ D d = new D(); System.out.println(d.value); d.say(); } class D{ private String value = "DDD"; private String name = "內部類"; public void say(){ System.out.println(C.this.name); System.out.println(name); run(); } } }
然後是建立內部類的兩種方式,顯然成員內部類是寄生於外部類的,建立內部類物件就必須先創造外部類。
public class Test10 { public static void main(String[] args) { /*方式1建立成員內部類物件*/ C c = new C(); C.D d = c.new D(); /*方式2建立成員內部類物件*/ C.D d1 = c.getClassD(); } } class C{ private String name = "外部類"; public void run(){ System.out.println("外部類奔跑"); } /*建立一個返回D物件的方法*/ public D getClassD(){ return new D(); } /*使用內部類的屬性和方法*/ public void eat(){ D d = new D(); System.out.println(d.value); d.say(); } class D{ private String value = "DDD"; private String name = "內部類"; public void say(){ System.out.println(C.this.name); System.out.println(name); run(); } } }
成員內部類前可加上四種訪問修飾符。
private:僅外部類可訪問。
protected:同包下或繼承類可訪問。
default:同包下可訪問。
public:所有類可訪問。
區域性內部類
區域性內部類存在於方法中。
他和成員內部類的區別在於區域性內部類的訪問許可權僅限於方法或作用域內。
class K{ public void say(){ class J{ } } }
注意事項:區域性內部類就像區域性變數一樣,前面不能訪問修飾符以及static修飾符。
匿名內部類
下面我們先通過一段程式碼初步瞭解一下匿名內部類。
public class Test13 { public static void main(String[] args) { driveCar(new Car(){ @Override public void drive() { System.out.println("駕駛著BMW汽車"); } }); } public static void driveCar(Car car){ car.drive(); } } interface Car { void drive(); }
分析以上程式碼知道靜態方法driveCar需要一個Car物件,我們通過實現介面建立一個匿名類物件傳遞過去。事實上還可以通過繼承類來建立一個匿名內部類物件。
注意事項:匿名內部類沒有構造方法。也是唯一沒有構造方法的內部類。匿名內部類和區域性內部類只能訪問外部類的final變數。