話不多說直接走起
1.怎么直接在外部 創建 內部類呢?
public class Demo { public static void main(String[] args) { Outer.Inner in=new Outer().new Inner(); in.show(); } } class Outer{ int a=3; public class Inner{ void show() { System.out.println("a="+a); } } public void method() { new Inner().show(); } }
要創建 Inner 對象 需要先創建 Outer 對象 因為 Inner類相當於是作為 Outer 類的一個屬性存在
然后再創建內部對象。這樣寫可能比較奇怪,然而它就是需要這樣創建的。
內部類可以直接使用 外部類的屬性或者方法的,不管外部類屬性和方法的權限是什么。
2.靜態內部類的創建
public class Demo { public static void main(String[] args) { Outer.Inner in=new Outer.Inner(); in.show(); } } class Outer{ private static int a=3; public static class Inner{ void show() { System.out.println("a="+a); } } public void method() { new Inner().show(); } }
此時靜態內部類相當於作為外部類的靜態屬性存在,他是隨着外部類的加載而加載的
3.非靜態內部類不能定義非靜態的屬性或者方法
public class Demo { public static void main(String[] args) { Outer.Inner.show(); } } class Outer{ private static int a=3; class Inner{ static void show() { System.out.println("a="+a); } } public void method() { new Inner().show(); } }
如上 Inner 類 里面是不能成功定義 show 方法的
這是為什么呢?
因為此時內部類Inner相當於是作為 外部類的 成員屬性存在的
假如我們可以定義成功。
只有 創建Outer實例的時候 內部類才會進行加載。
而如果我們直接這樣 Outer.Inner.show(); 調用內部類的靜態方法的時候
此時因為沒有 創建 Outer 對象 所以內部類 Inner 在內存中是不存在的,
更別說是這個類里面的方法了,所以非靜態內部類是不能定義靜態方法或者屬性的。
但是 如果定義的變量是 final 的,這是可以的。
public class Demo { public static void main(String[] args) { new Outer().new Inner().show(); } } class Outer{ private static int a=3; class Inner{ static final int b=4; void show() { System.out.println("a="+a); } } public void method() { new Inner().show(); } }
上述 內部類中的變量 b 是可以定義成功的。
這又是為什么呢?
因為我們看到的是 定義了一個常量,然后用常量,打印的時候,打印這個常量,
但是真實是在編譯完成之后,里面使用到的常量是直接替換成對應的值得,
所以,以下 對應的地方是直接替換成 數字 4 而不是常量對應的數字 4
void show() { System.out.println("a="+4); }
我們這樣書寫,只是為了代碼的可讀性而已。
4.內部類的繼承
public class Demo { public static void main(String[] args) { Outer outer=new Outer(); outer.method(); } } interface Father{ void show(); } class Outer{ private class Inner implements Father{ static final int b=4; public void show() { System.out.println("a="+b); } } public void method() { Inner aFather= new Inner(); aFather.show(); } }
5.內部類繼承的簡化形式 (匿名內部類)
如果只是用到了 接口中的方法,根本就不需要創建子類對象的引用,只需要引用父類就可以了
public class Demo { public static void main(String[] args) { Outer outer=new Outer(); outer.method(); } } interface Father{ void show(); } class Outer{ private class Inner implements Father{ static final int b=4; public void show() { System.out.println("a="+b); } } public void method() { Father aFather= new Inner(); aFather.show(); } }
可以進一步簡化,內部類的名字已經沒有意義了
public class Demo { public static void main(String[] args) { Outer outer=new Outer(); outer.method(); } } interface Father{ void show(); } class Outer{ public void method() { Father aFather= new Father() { static final int b=4; public void show() { System.out.println("a="+b); } }; aFather.show(); } }
這就是匿名內部類的使用
如果接口里面的方法只有一個的話,而且只調用一次的話,完全可以進一步簡化(可以使用匿名對象)
public class Demo { public static void main(String[] args) { Outer outer=new Outer(); outer.method(); } } interface Father{ void show(); } class Outer{ public void method() { new Father() { static final int b=4; public void show() { System.out.println("a="+b); } }.show(); } }
提醒:
內部類的定義就是為了控制他的訪問權限的,一般定義內部類就是為了不讓
外部對他進行訪問的,所以最好使用 private 來修飾內部類。