在初用java編程時,對內部類的瞭解相對較少。並且對內部類的需求並不是老是很明顯,也不知道使用的益處。但內部類是一種很是有用的特性,由於它容許你把一些邏輯相關的類組織在一塊兒,並控制位於內部類的可視性。內部類能不只與外圍類通訊,並且你用內部類寫出的代碼更加優雅而清晰。java
1.建立一個非靜態內部類.new 若是內部類的可見性不是public ,那麼它只能在外圍類中訪問到。但若是是public 就要以下建立:編程
public class Outer { class Inner{} public static void main(String[] args) { Outer outer = new Outer(); Inner inner = outer.new Inner(); } }
2.連接到外部類 當生成一個內部類的對象時,此時對象與製造它的外圍對象之間就有了一種聯繫,因此它能訪問其外圍對象的全部成員,而不須要任何特殊條件。此外內部類還擁有外圍類的全部元素的訪問權。這是如何作到?當某個外圍類的對象建立一個內部類對象時,此內部對象一定會祕密地捕獲一個指向那個外圍類對象的引用。但你能夠看到:內部類的對象只能在與其外圍類的對象相關聯的狀況下才能被建立。構建內部類對象時須要一個指向其外圍類對象的引用,若是編譯器訪問不到這個引用就會報錯。 3.得到外圍類的引用.this閉包
public class Outer { class Inner{ //從內部類中得到外圍類的實例自己 public Outer getOuterInstance(){ return Outer.this; } } }
4.在方法中定義類,在一個做用域中定義類ide
public class Outer { //在方法中定義類 public Inner definedClass1(){ class InnerImpl1 implements Inner{/*定義一個內部類*/} return new InnerImpl1(); } //在一個做用域中定義類 public Inner definedClass2(){ Inner inner = null; if(1==1){ class InnerImpl2 implements Inner{/*定義一個內部類*/} inner = new InnerImpl2(); } return inner; } }
5.在接口中的內部類,默認的是public satic 範圍的如測試
interface fruit{ class peach{} //這裏一個public static 級的內部類 }
6.內部類的閉包與回調,例子體現了一個內部類很好的設計如:ui
/** * 表示一個可吃的對象 */ public interface Eatable { <T extends EatWay<?>> T geEatWay(); /** * 吃的方式 * T 食物的種類 */ interface EatWay<T>{ T getFood(); //被吃的對象 void eat(); //吃的具體行爲 } }
public class Pear implements Eatable { @Override public EatWay<Pear> geEatWay() { return new PearEatWay(); } @Override public String toString() { return "梨"; } private class PearEatWay implements EatWay<Pear>{ @Override public Pear getFood() { return Pear.this; } @Override public void eat() { System.out.println("這是一種水果,可直接食用!"); } } }
public class Beef implements Eatable { @Override public EatWay<Beef> geEatWay() { return new BeefEatWay(); } @Override public String toString() { return "牛肉"; } private class BeefEatWay implements EatWay<Beef>{ @Override public Beef getFood() { return Beef.this; } @Override public void eat() { System.out.println("須要烹煮,可根據須要選擇烹煮的方式!"); } } }
測試:this
public static void main(String[] args) { Beef beef = new Beef(); EatWay<Beef> beefEatWay = beef.geEatWay(); System.out.println(beefEatWay.getFood()); beefEatWay.eat(); Pear pear = new Pear(); EatWay<Pear> pearEatWay = pear.geEatWay(); System.out.println(pearEatWay.getFood()); pearEatWay.eat(); }
結果: 牛肉 須要烹煮,可根據須要選擇烹煮的方式! 梨 這是一種水果,可直接食用!設計