java中的匿名類與匿名類面試題總結
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(); } } |