內部類是指在一個外部類的內部再定義一個類。
內部類分爲: 成員內部類、局部內部類、靜態嵌套類、匿名內部類 。
1、成員內部類
class Outer { private int i = 11; class Inner { private int i = 22; public void show() { int i = 33; System.out.println("內部類局部變量:" + i); System.out.println("內部類成員變量:" + this.i); System.out.println("外部類成員變量:" + Outer.this.i); } } } public class TestInner { public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner in = outer.new Inner(); in.show(); } }
運行結果:
內部類局部變量:33 內部類成員變量:22 外部類成員變量:11 |
成員內部類,就是作爲外部類的成員,可以直接使用外部類的所有成員和方法,即使是private的。
在外部類中如果要訪問成員內部類的成員,必須先創建一個成員內部類的對象,再通過指向這個對象的引用來訪問。
內部類可以用private、protected、public、default(默認)修飾。
如果成員內部類Inner用private修飾,則只能在外部類的內部訪問,如果用public修飾,則任何地方都能訪問;如果用protected修飾,則只能在同一個包下或者繼承外部類的情況下訪問;如果是默認訪問權限,則只能在同一個包下訪問。
外部類只能用public、default(默認)修飾。
成員內部類不能含有static的變量和方法。因爲成員內部類需要先創建了外部類,才能創建它自己的。
2、局部內部類
局部內部類是定義在一個方法或者一個作用域裏面的類。
它和成員內部類的區別在於局部內部類的訪問僅限於方法內或者該作用域內。
(1)定義在方法裏的內部類:
class Outer{ private int i=11; public void outShow(final int i){ class Inner{ public void inShow() { System.out.println("外部類outShow()方法傳入參數:"+i); System.out.println("外部類成員變量"+Outer.this.i); } } new Inner().inShow(); } } public class TestInner { public static void main(String[] args) { Outer out=new Outer(); out.outShow(22); } }
運行結果:
外部類outShow()方法傳入參數:22 外部類成員變量11 |
將內部類移到了外部類的方法中,然後在外部類的方法中再生成一個內部類對象去調用內部類方法。如果此時需要往外部類的方法中傳入參數,如out.outShow(22);,那麼外部類的方法形參必須使用final定義。
(2)定義在作用域內的內部類:
class Outer { private int i = 11; public void outShow(final boolean i) { if (i) { class Inner { public void inShow() { System.out.println("外部類outShow()方法傳入參數:" + i); System.out.println("外部類成員變量" + Outer.this.i); } } new Inner().inShow(); } } } public class TestInner { public static void main(String[] args) { Outer out = new Outer(); out.outShow(true); } }
運行結果:
外部類outShow()方法傳入參數:true 外部類成員變量11 |
3、靜態內部類
又叫靜態局部類、嵌套內部類、靜態嵌套類,就是修飾爲static的內部類。聲明爲static的內部類,不需要內部類對象和外部類對象之間的聯繫,就是說可以直接引用Outer.Inner,既不需要創建外部類,也不需要創建內部類。
class Outer{ private static int i=11;//靜態內部類只能訪問外部類的靜態成員變量,具有侷限性。 static class Inner{ public void inShow() { System.out.println("內部類普通方法訪問外部類靜態成員變量:"+i); } public static void sinShow() { System.out.println("內部類靜態方法訪問外部類靜態變量:"+i); } } } public class TestInner { public static void main(String[] args) { Outer.Inner in = new Outer.Inner(); in.inShow(); Outer.Inner.sinShow();//訪問靜態內部類靜態方法不需要創建對象 } }
4、匿名內部類
匿名內部類也就是沒有名字的內部類。
程序中有些類只使用一次,就可以使用匿名內部類簡化代碼書寫,省略一個類的書寫(如下例,省略Child類書寫)。
使用匿名內部類的前提條件:必須繼承一個父類或實現一個接口
(1)不使用匿名內部類
abstract class Person { public abstract void eat(); } class Child extends Person { public void eat() { System.out.println("Eat Something"); } } public class TestInner { public static void main(String[] args) { Person p = new Child(); p.eat(); } }
運行結果:
Eat Something |
(2)繼承抽象類的匿名內部類
abstract class Person { public abstract void eat(); } public class TestInner { public static void main(String[] args) { Person p = new Person() { public void eat() { System.out.println("Eat Something"); } }; p.eat(); } }
運行結果與上例相同,省略了Child類的書寫。
(3)實現接口的匿名內部類
interface Person { public abstract void eat(); } public class TestInner { public static void main(String[] args) { Person p = new Person() { public void eat() { System.out.println("Eat Something"); } }; p.eat(); } }
運行結果與上例相同,同樣省略了Child類的書寫。