1. 程式人生 > >java中的匿名類與匿名類面試題總結

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(???);

}

}

}

在控制分別輸出:302010

答案:(注意:內部類與外部類不存在繼承關係)

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();

}

}