java學習中,成員內部類、匿名內部類(java 學習中的小記錄)作者:王可利(Star·星星)
內部類:
一個類中定義另外一個類,這樣的類叫內部類。
內部類的文件名:外部類名$內部類名.class
內部類分兩種:
1.成員內部類
如何訪問成員內部類:
方式1:外部類中定義一個方法來創建內部類對象,再通過對象進行訪問。
方式2:可以直接在其他類中直接創建內部類這個對象,通過對象訪問。用點語。
格式:外部類名.內部類名 對象名 = new 外部類名().new 內部類名();
內部類使用的注意事項:
1.如果外部類和內部類中有同名的成員變量,那麼在內部類中java虛擬機默認訪問內部類中的成員變量,可以通過格式: 外部類名.this.變量名。
2.如果內部類中的成員被private 修飾了,那麼只能用方式1 來訪問內部類的成員。
3.內部類中有變量被 static 修飾了,那麼這個類也必須是一個靜態的類。
內部類使用的好處:
內部類中是可以直接訪問外部類的所有成員。實際上還是外部類自己調用的。外部類擁有內部類。
一般什麼時候使用內部類:
我們在描述一個A對象,發現A對象中又需要有一個對象B,對象B很復雜,B對象又想訪問A中的數據。這個時候用內部類來描述B對象就更方便了。
又比如說:人有心髒,人也有血液。人是一個類,心髒是一個類,血液也是一個類。 那麼心髒想訪問血液的話就很麻煩。
1 package study; 2 3 class Outer { 4 5 int i = 10;//自帶的成員變量 外部類 6 7 //定義一個內部類 8 //成員內部類 9 class Inner{ 10 11 int i = 20;//內部類的變量 12 13 public void print() { 14 System.out.println("這個是內部類"+i);//打印的是20 15 System.out.println("這個是內部類"+Outer.this.i);//訪問的是外部類的屬性 16 } 17 } 18 //創建一個方法來創建內部類對象(方式1) 19 /* public void instantce(){ 20 //創建內部類對象 21 Inner inner = new Inner(); 22 inner.print(); 23 }*/ 24 } 25 //其他類 26 public class star { 27 public static void main(String[] args) { 28 /* //在其他類中訪問內部類(方式1) 29 Outer outer= new Outer(); 30 outer.instantce();*/ 31 32 //其他類中直接訪問:(方式2) 33 Outer.Inner inner = new Outer().new Inner(); 34 inner.print(); 35 36 } 37 }
2.局部內部類
局部內部類:在類方法中定義的類,這樣的一個類叫局部內部類。
局部內部類只能通過第一種方式來訪問。
局部內部類使用注意點:
如果局部內部類訪問了方法中的局部變量,方法中的局部內部類必須用final來修飾。
1 class Outer{ 2 String name = "外部類的name"; 3 int i = 20; 4 5 public void test() { 6 7 final int i = 30;//局部變量 出了這個方法就消失。 8 //為什麼要用final來修飾? 9 /*test方法執行完,變量i 立馬從內存中消失,而inner對象在方法執行完之後,沒有消失的,這裡再使用i就好比把i的生命周期延遲了,與局部變量的定義不符。 10 *所以用final修飾,相當於把i設置了一個復制品給test方法使用,真實的i已經消失。 11 * */ 12 13 //局部內部類 14 class Inner{ 15 public void print(){ 16 /*int i = 10; 注銷之後研究拿到30這個i*/ 17 System.out.println("這個是局部內部類的方法"+i);//打印的是10 18 } 19 } 20 //創建局部對象 21 Inner inner = new Inner();//test走完,這個對象可能還存在(它是由java虛擬機決定消除的,不知道是什麼時候),存在的話相當於給 i 的生命周期延遲了。 22 inner.print(); 23 } 24 } 25 26 public class Star { 27 28 public static void main(String[] args) { 29 //在其他類中訪問局部內部類 30 Outer out = new Outer(); 31 out.test(); 32 33 //下面是錯誤的寫法 34 /*Outer.Inner inner = new Outer().new Inner(); 35 inner.print();*/ 36 } 37 }
匿名的內部類(沒有類名的類)
好處:簡化書寫
匿名內部類使用前提:外部類必須有繼承或者實現關系。
因為它沒有名字,它實際創建出來是靠父類來創建的,以多態表現出來的。所以要繼承或實現關系。
它的實現實際以多態的形式表現的所以需要滿足上面的條件。
匿名內部類一般用於實際參數的傳遞。(和匿名對象用法一樣)
abstract class Animal{ public abstract void run(); public abstract void sleep(); } //外部類 //在Outer裡面創建一個Dog的內部類 class Outer{ //不用匿名 /*class Dog extends Animal{ public void run() { System.out.println("狗在跑"); } public void sleep() { System.out.println("狗在睡覺"); } }*/ public void print(){ //Dog d = new Dog(); //d.run(); //匿名的Dog(通過父類來完成創建) //匿名內部類:只是沒有名字,其它的和普通的類沒什麼不一樣 Animal a = new Animal(){//不是父類創建對象 匿名內部類(子類) //具體實現 public void run(){ System.out.println("狗在跑"); }; public void sleep(){ System.out.println("狗在睡覺"); }; }; a.run(); a.sleep(); }; } public class Star { public static void main(String[] args) { Outer out = new Outer(); out.print(); } }