1.概述:把類定義在其他類的內部,這個類就稱爲內部類。
如:類B定義在類C中,B就是C的內部類。
class C{ //B爲類A的內部類 class B{ } } |
2.訪問特點:
(1)內部類可以直接訪問外部類的成員,包括私有成員;
(2)外部類訪問內部類成員,必須創建對象,通過對象訪問。
class C{ //B爲類A的內部類 private int num=10; class B{ public int Bnum=20; public void show() { //內部類直接訪問外部類的成員 System.out.println(num); } } public void show1() { //直接訪問內部類對應成員,報錯 //System.out.println(Bnum); //通過創建內部類對象訪問,成功 B b=new B(); System.out.println(b.Bnum); } }
|
3.內部類的分類
根據內部類的位置不同,可將內部類分爲成員內部類、局部內部類。
class C{ //成員內部類 class B{ } public void show1() { //局部內部類 class D{ } } } |
4.成員內部類
成員內部類的訪問格式:
外部類名.內部類名 對象名=外部類對象.內部類對象
class C{ //成員內部類 class B{ public void show() { System.out.println("你好"); } } }
public class niming { public static void main(String[]args) { //創建對象訪問對應內部類函數成員 C.B b=new C().new B(); b.show(); } } |
雖然內部類可以以上述方式訪問,但實際開發中,常將內部設爲私有成員,以保護數據的安全,不讓外部直接使用
(1)將內部類設爲私有成員的使用方法
class C{ //成員內部類,設爲私有 private class B{ public void show() { System.out.println("你好"); } } public void show1() { B b=new B(); b.show(); } }
public class niming { public static void main(String[]args) { //創建對象訪問對應內部類函數成員 C c=new C(); c.show1(); } } |
(2)將內部類設爲靜態類
特定:靜態內部類訪問外部類成員時,只能訪問外部類的靜態成員
class C{ //靜態成員變量 private static int num=20; //靜態成員方法 public static void show2() { System.out.println("hello world"); } //成員內部類,設爲私有靜態 private static class B{ public void show() { System.out.println(num); show2(); } } public void show1() { B b=new B(); b.show(); } } public class niming { public static void main(String[]args) { //創建對象訪問對應內部類函數成員 C c=new C(); c.show1(); } } |
Private 與 static修飾內部類的特點
Private 保證了數據的安全
Static 讓數據訪問更方便
(3)成員內部類面試題
補齊程序 class Outer { public int num = 10; class Inner { public int num = 20; public void show() { int num = 30; System.out.println(?); System.out.println(??); System.out.println(???); } } } 在控制分別輸出:30,20,10 |
答案:(注意:內部類與外部類不存在繼承關係)
class Outer { public int num = 10; class Inner { public int num = 20; public void show() { int num = 30; //三個變量對應的變量名相同 System.out.println(num);//訪問的是本方法中的num變量,滿足就近原則 System.out.println(this.num);//通過this變量,訪問方法外,本類中的變量,this代表Inner類對象 System.out.println(Outer.this.num);//通過外部類名加this,返回外部類對象,訪問對象外部類的num //System.out.println(new Outer().num); //通過創建對象的方式訪問外部成員變量不推薦 } } } public class niming { public static void main(String[]args) { Outer.Inner inner=new Outer().new Inner(); inner.show(); } } |
5.局部內部類
(1)可以直接訪問外部類的成員
class C{ //靜態成員變量 private int num=20; //局部內部類訪問外部類成員 public void show1() { class B{ public void show() { System.out.println(num); } } } } |
(2)方法內部通過創建內部類的對象來訪問局部內部類的成員
class C{ //靜態成員變量 private int num=20; //局部內部類訪問外部類成員 public void show1() { class B{ public void show() { System.out.println(num); } } B b=new B(); b.show(); } public void show2() { B b=new B();//此處報錯 //原因:局部內部類在在方法中定義,隨着方法的調用產生,隨着方法調用完消失,所以不能用此方法直接創建對象 } } |
(3)局部內部類訪問局部變量
1)局部內部類訪問局部變量時,必須用final修飾局部變量
2)原因:方法中的局部變量在方法調用時產生,在方法調用後消失,若方法消失後,內部類就不能再訪問局部變量,但用final修飾後,在編譯之後,產生的字節碼中,會將對應的final修飾的變量認成常量,即內部類訪問的是常量值
class C{ //靜態成員變量 private int num=20; //局部內部類訪問外部類成員 public void show1() { final int testNum=30; class B{ public void show() { System.out.println(num); System.out.println(testNum); //編譯後,此句變爲 //System.out.println(30); } } B b=new B(); b.show(); } } |
6.匿名內部類
(1)概念:即內部類的簡化寫法
(2)前提:存在一個類(可以是具體類也可以是抽象類) 或接口
(3)格式:new 類名或接口名{重寫的方法}
(4)本質:創建的是繼承了類或實現了接口的子類匿名對 象。
interface D{ void ShowContext(); } class B{ public void show() { //匿名內部類的實現 new D(){ @Override public void ShowContext() { System.out.println("hello"); } }; }; } |
(5)匿名內部類方法的訪問
//方法1:直接在new A內部類後邊加點加方法,這樣訪問,如果方法多了,調用太麻煩 new D(){ @Override public void ShowContext() { System.out.println("hello"); } }.ShowContext(); //方法2:通過創建對象來訪問,多態思想 D a=new D(){ @Override public void ShowContext() { System.out.println("hello"); } }; a.ShowContext(); |
(6)匿名內部類在開發中的使用,一般是方法參數爲接口的情況
interface D{ void ShowContext(); } class B{ //參數爲接口對象 public void show(Dd) { d.ShowContext(); } }
public class niming { public static void main(String[]args) { B b=new B(); //調用時使用匿名類創建匿名對象 b.show(new D(){ @Override public void ShowContext() { // TODO Auto-generated method stub System.out.println("hello"); } }); } } |
(7)匿名內部類的面試題
interface Inter { void show(); } class Outer { //補齊代碼 } class OuterDemo { public static void main(String[] args) { Outer.method().show(); } } 要求在控制檯輸出”HelloWorld”
|
答案:
//思路:Outer.method() 說明method()爲Outer類中的靜態方法 // Outer.method().show();因爲method()後邊用點調用了對應的方法,相當於一個對象調用某個方法,而show方法又是接口Inter中的方法, //即想到method應返回一個Inter的實現類對象,而又不能創建新對象,所以想到使用匿名類 interface Inter { void show(); } class Outer { public static Inter method() { return new Inter() { @Override public void show() { System.out.println("hello world"); } }; } } public class niming { public static void main(String[]args) { Outer.method().show(); } } |