內部類(嵌套類)

嵌套類是指被定義在另外一個類的內部的類。java

嵌套類存在的目的是:只是爲它的外部類提供服務;多線程

outer.java裏面定義了一個內部類inner,運行時,一旦編譯成功,就會生成兩個徹底不一樣的.class文件,分別是outer.class和outer$inner.class。ide

嵌套類分爲四種:靜態成員類,非靜態成員類(成員內部類),匿名類,局部類。測試

內部類:非靜態成員類(成員內部類),匿名類,局部類。spa

1.靜態內部類

 1 public class Outer {  2 
 3     public static String name = "Joe";  4     private String password = "0806";  5 
 6     //靜態內部類
 7     public static class inner{  8         public static void print1(){  9  System.out.println(name); 10             //調用外部類的靜態方法
11  outerPrint(); 12  } 13         public void print2(){ 14  System.out.println(name); 15  } 16  } 17 
18     public static void outerPrint(){ 19         System.out.println("Outer static method!"); 20  } 21 
22     public static void main(String[] args){ 23        //靜態內部類的靜態方法調用
24  Outer.inner.print1(); 25         //靜態內部類的非靜態方法調用
26         Outer.inner inner = new Outer.inner(); 27  inner.print2(); 28  } 29 }

輸出結果:線程

Joe
Outer static method!
Joecode

經過這個例子能夠看出:對象

  ♥ 靜態內部類中能夠有靜態方法,也能夠有非靜態方法;blog

  ♥ 靜態內部類只能訪問其外圍類的靜態成員和靜態方法;繼承

  ♥ 和普通的類同樣,要訪問靜態內部類的靜態方法,能夠直接「.」出來,不須要一個實例;

  ♥ 要訪問靜態內部類的非靜態方法,必須拿到一個靜態內部類的實例對象;

  ♥ 實例化靜態內部類:外圍類.內部類  xxx = new 外圍類.內部類();

能夠把靜態內部類看做普通的類,只是碰巧被聲明在另外一個類的內部而已;若是靜態內部類被聲明爲私有的,那麼它就只能在外圍類的內部才能夠訪問。

非靜態成員類(成員內部類)

成員內部類是最多見的內部類,就是在外部類的基礎上按照通常定義類的方式定義類,舉個例子:

 1 public class Outer {  2 
 3     public static String name = "Joe";  4     private String password = "0806";  5 
 6     //私有成員內部類
 7     private class PrivateInner{  8         public void print1(){  9             System.out.println("private " + name); 10             System.out.println("public " + password); 11             //調用外部類的靜態方法
12  outerPrint(); 13  } 14  } 15     //公有的成員內部類
16     public class PublicInner{ 17         public void print2(){ 18             String password = "0810"; 19             System.out.println("public " + name); 20             System.out.println("public " + password); 21             //調用外部類的靜態方法
22  outerPrint(); 23  } 24  } 25     public static void outerPrint(){ 26         System.out.println("Outer static method!"); 27  } 28 
29     public static void main(String[] args){ 30         Outer outer = new Outer(); 31  Outer.outerPrint(); 32         //實例化私有成員內部類
33         Outer.PrivateInner privateInner = outer.new PrivateInner(); 34  privateInner.print1(); 35         //實例化公有成員內部類
36         Outer.PublicInner publicInner = outer.new PublicInner(); 37  publicInner.print2(); 38  } 39 }

輸出結果:

Outer static method!
private Joe
public 0806
Outer static method!
public Joe
public 0810
Outer static method!

經過這個例子能夠看出:

  ♥ 成員內部類是依附其外圍類而存在的,若是要產生一個成員內部類,必須有一個其外圍類的實例;

  ♥ 成員內部類不能夠定義靜態方法和靜態屬性;

  ♥ 聲明爲private的成員內部類,只對其外圍類可見;聲明爲public的成員內部類,其餘非外圍類對其可見;

  ♥ 成員內部類能夠訪問外圍類的私有屬性,若是成員內部類的屬性和其外圍類的屬性重名,則以成員內部類的屬性值爲準;

  ♥ 實例化成員內部類:外圍類.內部類 xxx = 外圍類.new 內部類();

匿名內部類

在多線程的模塊中代碼,大量使用了匿名內部類,以下:

 1 public class Outer {  2     //匿名接口
 3     interface Inner{  4         int getNumber();  5  }  6     //使用匿名接口
 7     public Inner getInner(final int num,String str){  8         return new Inner() {  9  @Override 10             public int getNumber() { 11  System.out.println(str); 12                 return num; 13  } 14         }; /* 注意:分號不能省 */
15  } 16     //測試
17     public static void main(String[] args){ 18         Outer outer = new Outer(); 19         Inner inner = outer.getInner(4,"nihao"); 20  System.out.println(inner.getNumber()); 21  } 22 }

輸出結果:

nihao 4

 經過這個例子能夠看出:

  ❤ 匿名內部類沒有修飾符;

  ❤ 當所在方法的形參須要被匿名內部類使用時,該形參必須爲final,由於:內部類在編譯時會生成一個獨立的.class文件,改文件並不在它的外圍類中,內部類將傳過來的參數經過本身的構造器備份到了本身的內部,這樣本身內部方法的調用其實是本身的屬性,而不是外圍類方法的參數;簡單理解就是:拷貝引用,爲了不引用值發生改變,例如被外圍類的方法修改等,而致使內部類獲得的值不一致,因而用final修飾讓該引用不可變;

  ❤ 匿名內部類沒有構造方法,由於它連名字都沒有;

  ❤ new 匿名內部類;這個類必須先存在;

局部內部類

局部內部類:是指內部類定義在方法和做用域內。

看個例子:

 1 public class Outer {  2     private void internalTracking(boolean b) {  3         if (b) {  4             //局部內部類
 5             class TrackingSlip {  6                 private String id;  7  TrackingSlip(String s) {  8                     id = s;  9  } 10  String getSlip() { 11                     return id; 12  } 13  } 14             TrackingSlip ts = new TrackingSlip("slip"); 15             String s = ts.getSlip(); 16  } 17  } 18 
19     public void track() { 20         //調用方法(含有局部內部類)
21         internalTracking(true); 22         System.out.println("......."); 23  } 24 
25     public static void main(String[] args) { 26         Outer p = new Outer(); 27  p.track(); 28  } 29 }

局部內部類也會像其餘類同樣編譯,只是做用域不一樣而已,只有在該方法或者做用域內才能用,超出做用域或者方法就不可引用。

  ❤ 局部內部類沒有訪問修飾符;

  ❤ 局部內部類要訪問外圍類的對象或者變量,那麼這個變量或者對象必須是final修飾的;

內部類的好處

  ❤ Java運行實現多個接口,但不容許繼承多個類,使用內部類能夠解決Java不容許多個繼承的問題。在一個類的內部定義一個內部類,讓這個內部類繼承某個原有的類,而這個內部類又能夠訪問外圍類的屬性和方法,這樣就至關於多個繼承了;

  ❤ 有效的對外隱藏了本身,增長了本身的私密性;

  ❤ 使用內部類可讓類與類之間的聯繫更加緊密;

  ❤ 有些類知道只會在某個地方使用只使用一次,爲這種類建立一個外部類顯然沒有必要,因此這種就寫個內部類用用就能夠了;

相關文章
相關標籤/搜索