面向對象程序設計(三)
(10)內部類,在類的內部聲明類成為內部類,可以分為匿名內部類和實名內部類。
實名內部類:在類體中定義與普通類的定義方法相同也可以繼承父類,實現接口,而且訪問模式還多了protected和private。在外部類內的使用和普通類使用一樣,例如定義一個內部類in如下:
public class inner {
int m;
double d;
public inner()
{
m=9;
d=2.3;
b=new in();
}
in b;
class in
{
static int Z=56;
int m;
double d;
public in()
{
m=15;
d=5.0;
}
}
可以看到在外部類inner的構造函數中中間可以直接使用內部類。內部類也可以直接使用外部類的成員。在外部類外部有兩種創建內部類實例方式,第一種是創建靜態實名內部類對象:
inner.in ii=new inner.in(); //結果報錯。
原因是要創建靜態實名內部類對象,但前面內部類沒有加上修飾詞static因此無法創建,修改後再次調用
inner.in ii=new inner.in(); //可改為in ii=new inner.in();,結果不受影響。
System.out.println(ii.d); //調用非靜態成員或方法
System.out.println(in.Z); //調用靜態成員或方法,可以in.Z、ii.Z、inner.in.Z均正確,但使用諸如i.Z、inner.Z、inner.ii.Z、i.ii.Z、i.in.Z都是錯誤的,其中inner和i是外部類名和對象名,而in和ii是內部類名和對象名
輸出結果
5.0
56
同理調用靜態成員方法和靜態成員域也是相同的操作。
第二種創建非靜態實名內部類:
inner.in ii=i.new in(); //可改為in ii=i.new in(); ,結果不受影響。同樣的內部類不能有static修飾,否則報錯。
System.out.println(ii.d); //調用非靜態成員。
System.out.println(in.Z); //調用靜態成員域,適用情況同上,非靜態實名內部類中不能聲明定義靜態成員方法,若想要定義靜態成員域必須同時加上修飾詞final。
關於static塊也是只能在static內部類中有,否則出錯,其余事項無變化
匿名內部類:不能抽象、靜態、派生子類。
有如下代碼:
class outer { int a=0; int h; public outer(int a,int h) { this.a=a; this.h=h; } void f() { System.out.println("anony"); } } public class anony { public static void main(String []args) { outer b=new outer(5,10) { int a=6; void f(){System.out.println(a);} }; //匿名內部類一定要加分號 System.out.println(b.a); //5,調用父類同名成員域 b.f(); //6,調用子類重寫成員方法,成員方法調用子類成員域 } }
其中的outer可以是一個類名,此時匿名內部類是以此類為父類的子類,並構造上轉型實例對象,與普通上轉型並無差別(存疑,部分性質有待驗證)。若是接口名,參數列表可以為空,是實現接口所有抽象方法的類,這時間也是接口的聲明對象(接口也是可以聲明對象,類似於上裝型的那種)。
(11)變量作用域及參數傳遞方式
靜態成員域具有全局作用範圍,其他成員域——即非靜態成員域,類體中的方法及子類中的方法是它的作用範圍,且聲明語句可在方法體之前之後的類體中均可。
在成員方法或構造方法中定義的語句成為局部變量只在函數體中有效;for語句初始化只在for語句中使用,結束後失效,但在C/C++中不失效仍可繼續使用,註意區分。
面向對象程序設計(三)