Java筆記之內部類、匿名內部類詳解
阿新 • • 發佈:2018-12-14
內部類
內部類訪問特點:
1、內部類可以直接訪問外部類中的成員
2、外部類要訪問內部類,必須建立內部類的物件
class Outer { private int num=3; class Inner //內部類 { void show() { System.out.println("show run..."+num);//直接訪問 } } public void method() { Inner in =new Inner();//需要建立內部類的物件 in.show(); } }
一般用於類的設計
分析事物時,發現該事物描述中還有事物,而且這個事物還在訪問被描述事務的內容。
這時就把還有的事物定義成內部類來描述。
先說明一下static ,隨著類的載入,static 變數首先被載入進記憶體!
class Outer { private static int num =3; static class Inner //內部類 { void show () { System.out.println("show run..."+num); } static void function ()//如果該內部類中定義了靜態成員,這個內部類必須是靜態的。 { System.out.prtintln("function"+num); } } public void method () { Inner in =new Inner(); in.show(); }
class InnerClassDemo { public static void main (String[] args) { //Outer out =new Outer(); //out.method(); //直接訪問外部類中的內部類中的成員 //Outer.Inner in =new Outer().new Inner(); //in.show(); //如果內部類是靜態的。相當於一個外部類 Outer.Inner in =new Outer.Inner(); in.show(); //如果內部類時靜態的,成員是靜態的,則: Outer.Inner.function(); } }
為什麼內部類能直接訪問外部類中的成員呢?
那是因為內部類持有了外部類的引用。 呼叫方法:外部類名.this.成員名
class Outer
{
int num =3;
class Inner
{
int num =4;
void show ()
{
int num =5;
System.out.println(Outer.this.num);
}
}
void method ()
{
new Inner().show();
}
}
內部類可以存放在區域性位置上,內部類在區域性位置上只能訪問區域性中被final修飾的區域性變數(常量)
class Outer
{
int num =3;
void method(final int y )
{
final int x=0;//從內部類中訪問區域性變數x,需要被宣告為最終型別
class Inner
{
void show()
{
System.out.println("show..."+num);
System.out.ptintln("show..."+x);//從內部類中訪問區域性變數x,需要被宣告為最終型別
System.out.println("show..."+y);//從內部類中訪問區域性變數x,需要被宣告為最終型別
}
}
Inner in =new Inner();
in.show();
}
//不能在另外一個方法裡面建立Inner物件,因為她不知道這個方法裡面有inner
}
匿名內部類。就是內部類的簡寫格式。
必須由前提。
內部類必須繼承或者實現一個外部類或者介面。
匿名內部類:其實就是一個匿名子類物件
格式:new 父類or介面(){子類內容}
abstract class Demo
{
abstract void show1();
abstract void show2();
}
/*通常的使用場景之一:
當函式引數是介面型別時,而且介面中的方法不超過三個
可以用匿名內部類作為實際引數進行傳遞
*/
class Outer
{
int num =4;
public void method()
{
Demo in=new Demo() //匿名內部類
{
void show()
{
System.out.println("show1......"+num);
}
void show2()
{
System.out.println("show2......"+num);
}
};
in.show1();
in.show2();
}
}
匿名內部類的應用:
/*通常的使用場景之一: 當函式引數是介面型別時,而且介面中的方法不超過三個 可以用匿名內部類作為實際引數進行傳遞 */
inerface Inter
{
void show1();
void show2();
}
class Demo_Inner
{
public static void main(String[] args)
{
System.out.println("Hello world!");
show(new Inter()
{
public void show1();
public void show2();
});
}
public static void show(Inter in )
{
in.show1();
in.show2();
}
}
面試題,重要!
1、
class Outer
{
void method()
{
new Object()
{
public void show()
{
System.out.println("show run");
}
}.show(); //編譯成功
}
}
2、
class Outer
{
void method()
{
Object obj = new Object()
{
public void show()
{
System.out.println("show run");
}
};
obj.show();//編譯失敗:因為匿名內部類這個子類物件被向上轉型為Object型別
//這樣就不能再使用子類特頭的方法了。
}
}