外部類:包含內部類的類。java
內部類: 把一個類放在另外一個類的內部。測試
形式: public class 外部類{
【修飾符】【訪問控制符】class 【類名】{spa
}code
}對象
做用: 1。內部類提供了更好的封裝,能夠把內部類隱藏在外部類以內,不容許同一個包中的其餘類訪問該類。繼承
2。內部類成員能夠直接訪問外部類的私有數據,由於內部類被當成其外部類成員,同一個類的成員之間能夠互相訪問。接口
public class Out{ private int a= 12; public class Int{ public void say(){ System.out.println(a);//直接訪問外部類私有屬性 } } public void test(){ Int i = new Int();//外部類不能直接訪問非靜態內部類的實例屬性,必須顯式建立內部類對象 i.say(); } public static void main(String[] args){ Out o = new Out();//只是建立了外部類,還未建立內部類對象 o.test(); } }
PS:非靜態內部類對象中保留外部類對象的引用。 get
非靜態內部類不能有靜態方法,靜態屬性,靜態初始化塊。it
非靜態內部類的對象必須寄存在外部類的對象裏,所以建立非靜態內部類以前,必須先建立其外部類的對象。class
靜態內部類能夠包含靜態成員,也能夠包含非靜態成員。靜態內部類不能訪問外部類的實例變量,只能訪問外部類的類成員。即便靜態內部類的實例方法也不能訪問外部類的實例成員。
靜態內部類是外部類的類相關,而不是外部類的對象相關的,也就是說,靜態內部類的對象不是寄存在外部類對象裏的,而是寄存在外部類的類自己中。當一個靜態內部類的對象存在時,並不存在一個被它寄存的外部類對象,靜態內部類的對象裏只有外部類的類引用,沒有外部類對象的引用。
3。 匿名內部類適合用於建立那些僅須要一次使用的類。
外部類之外定義內部類: Outclass.Inclass var;
外部類之外建立內部類實例:Outclass.new Inclass();
class Out { //定義一個非靜態內部類,不使用訪問控制符,即同一個包中其餘類可訪問該內部類 class In { public In(String msg) { System.out.println(msg); } } } public class CreateInnerInstance { public static void main(String[] args) { Out.In in = new Out().new In("測試信息"); /* 上面代碼可改成以下三行代碼: 使用OutterClass.InnerClass的形式定義內部類變量 Out.In in; 建立外部類實例,非靜態內部類實例將寄存在該實例中 Out out = new Out(); 經過外部類實例和new來調用內部類構造器建立非靜態內部類實例 in = out.new In("測試信息"); */ } }
非靜態內部類的構造器必須使用外部類對象來調用
public class SubClass extends Out.In { //顯示定義SubClass的構造器 public SubClass(Out out) { //經過傳入的Out對象顯式調用In的構造器 out.super("hello"); } }
匿名內部類: 建立匿名內部類時會當即建立一個該類的實例。 1 不能是抽象類 2 不能定義構造器 3 能夠定義實例初始化塊
new 父類構造器(實參列表) |實現接口()
{
//匿名內部類的類體部分
}
匿名內部類必須繼承一個父類,或實現一個接口,但最多隻能繼承一個父類或實現一個接口。
最經常使用的建立匿名內部類的方式是 :須要建立某個接口類型的對象。
interface Product //接口 { public double getPrice(); public String getName(); } public class TestAnonymous { public void test(Product p) { System.out.println("購買了一個" + p.getName() + ",花掉了" + p.getPrice()); } public static void main(String[] args) { TestAnonymous ta = new TestAnonymous(); //調用test方法時,須要傳入一個Product參數,此處傳入其匿名實現類的實例 ta.test( new Product() { public double getPrice() { return 567.8; } public String getName() { return "AGP顯卡"; } }); } }