定義在另外一個類中的類稱之爲內部類,典型的應用是外部類將有一個方法,它返回一個內部類的引用。app
public class Test { public static void main(String[] args){ Outer o = new Outer(); Outer.Inner i = o.showInner(); //OuterName.InnerName表示內部對象類型 System.out.println(i.getName()); } } class Outer{ class Inner{ private String name; Inner(){ name = "sakura"; } public String getName() { return name; } } Inner showInner(){ return new Inner(); //外部類的方法,返回一個內部對象的引用 } }
內部類有外部類全部成員的訪問權限。 事實上,某個外部類對象建立了一個內部類對象是,該內部類對象會祕密捕獲一個指向外部類對象的引用,在訪問外部類成員時,將用那個引用訪問。this
1)在外部建立內部類對象時聲明內部類對象類型爲 //OuterClassName.InnerClassNamespa
2)在外部建立內部類對象須要引用外部類對象,構造語法爲 //OuterObjectName.new InnerClassName(parameters)code
3)生成外部類對象的引用:外部類名稱緊跟圓點緊跟this //OuterClassName.this對象
public class Test { public static void main(String[] args){ Outer o = new Outer(); Outer.Inner i = o.new Inner(); //1)和2) } } class Outer{ private String name = "sakura"; Outer(){ } public String getName() { return name; } public class Inner{ Inner(){ System.out.println(Outer.this.getName()); //3) } } }
1)局部內部類不能用public 或private 訪問說明符進行聲明。它的做用域被限定在聲明這個局部類的塊中。blog
2)局部內部類對外界徹底隱藏,只有所在方法能夠知道它的存在。繼承
3)它們不只可以訪問包含它們的外部類, 還能夠訪問局部變量。不過, 在jdk8以前,那些局部變量必須事實上爲final。接口
public class OuterClass { private String str = "OutStr"; public void OuterMethod(String str1) { System.out.println("OuterMethod"); class InnerClass //局部內部類 { public InnerClass() {} public void InnerMethod() { System.out.println("InnerMethod"); } public void InnerShow() { System.out.println(str); System.out.println(str1); InnerMethod(); } } InnerClass inner = new InnerClass(); inner.InnerMethod(); inner.InnerShow(); } public static void main(String[] args) { OuterClass test = new OuterClass(); test.OuterMethod(test.str); } }
1)匿名類有兩種實現方式:作用域
繼承一個類,重寫其方法。get
實現一個接口(能夠是多個),實現其方法。
new SuperType(construction parameters) { inner class methods and data } new InterfaceType { methods and data }
匿名內部類實現接口
public class Test {
public Contents contents(){
return new Contents(){ //匿名內部類,實現接口
int i = 0;
public int value(){return i;}
};
}
public static void main(String[] args){
Test t = new Test();
Contents c = t.contents();
}
}
interface Contents{
int value();
}
匿名內部類繼承父類
public class Test { public Wrapping wrappering(int x){ return new Wrapping(x){ //匿名內部類,繼承父類 public int value(){ return super.value(); } }; } public static void main(String[] args){ Test t = new Test(); Wrapping w = t.wrappering(10); } } class Wrapping{ private int i; public Wrapping(int x){ i=x;} public int value(){return i;} }
2)匿名內部類沒有構造器,但能夠有構造體
public class Test { public Contents contents(){ return new Contents(){ //匿名內部類 int i; { //構造體 i = 0; System.out.printf("i:" + i); } public int value(){return i;} }; } public static void main(String[] args){ Test t = new Test(); Contents c = t.contents(); } } interface Contents{ int value(); }
1)有時候, 使用內部類只是爲了把一個類隱藏在另一個類的內部,並不須要內部類引用外圍類對象。爲此,能夠將內部類聲明爲static(靜態內部類), 以便取消產生的引用。
2)靜態內部類不能訪問非靜態的外部類對象;建立靜態內部類對象不須要經過外部類對象。
3)靜態內部類能夠有靜態域和方法。
public class Test { public static void main(String[] args){ Outer o = new Outer(); Outer.Inner i = new Outer.Inner(); //直接經過類名建立,對比於 o.new Inner(); } } class Outer{ private String name = "sakura"; Outer(){ } public String getName() { return name; } public static class Inner{ static int id = 20151003; //靜態域ok static String show_id(){ //靜態方法ok return ""+id; } Inner(){ //System.out.println(Outer.this.getName()); 報錯,沒法訪問外部類成員 } } }
class withinner{ withinner(){ } class inner{ } } public class Test extends withinner.inner{ Test(withinner w){ w.super(); //外部類引用.super() } public static void main(String[] args) { Test t = new Test(new withinner()); } }
每一個內部類都能獨自得實現一個接口,無論它的外部類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。