2013年12月15日 星期日

[JAVA] inner class 解析 (轉)

InnerClass 是在JAVA中常見的使用方法
顧名思義,就是有個Class包在另一個Class裡面
如果才接觸JAVA或者對物件導向程式設計並沒有很熟的人,知道這樣就夠了,因為在摸透整個物件設計理念之前,嘗試了解InnerClass 並不是一件聰明的選擇,只會讓人更加頭昏眼花而已@_@ (技能無法使用,需求:物件導向程式設計等級2)
但是如果對JAVA已經有點小熟,你一定已經用過InnerClass ,只是對其使用觀念還有些模糊,這樣的話你就已經解鎖了這項技能,如果你手上還有技能點,請大方地獻給InnerClass 吧!( ̄▽ ̄
難度不高,但是需要一些背景知識
在學習InnerClass 之前,先來了解一下專有名詞吧
1.Member <=>Static Member
=====================
Member: 直屬Class底下的都可稱為Member 
Member 變數稱: instance field
Member Method稱: instance Method
Member Class 就是Member Class
=====================
Static Member變數稱: class field
Static Member Method稱: class Method
Static Member Class 就是Static Member Class
=====================
總之,冠上Static 的東西,就是class 等級的,不需要實體化就可以使用
非Static 的東西就必須要成為instance 才可以使用


2.區域名詞

class ExampleClass{
//field area
//全域

void method(){
//local area
//區域

}
}
這樣一來,InnerClass 會用到的名詞大概都介紹了
名詞介紹可以先不用看得太仔細,寫名詞介紹主要只是為了等一下看InnerClass 時可能會有理解上的困難,或是翻譯上的誤差,用來對照用的╮( ̄▽ ̄)╭

進入正題了…
JAVA中的Class分成2種類
1.一般Class
2.InnerClass (內部類別)
(JAVA沒有像C++的巢狀類別
現在我們要介紹的就是InnerClass

其中InnerClass又有3種狀態,依所存在的位置而決定
中文翻譯使用位置英文原文範例
1.成員式在class中Member inner classclass ExampleClass{
class InnerClass(){
//這就是成員式
//

}
}
2.區域式在method中Local inner class (Local Classes)class ExampleClass{
void method(){
class InnerClass(){
//這就是區域式
//
}
}
}
3.匿名式在宣告同時Anonymous inner class(AIC)class ExampleClass{
void method(){
addActionListener(new ActionListener(){
//這就是匿名式
//
});
}
}

其實下面的才是重點…
這3種InnerClass 可以使用變數的權限,以及被使用的方式(不說方法,怕混淆XD)

innerClass的使用變數權限:
成員式Member inner class
所有field/method均可自由使用

區域式Local inner class
所有field/method均可自由使用
Local variables 必須標記為final才可以使用 ㊟1
 如果Local和Field有同名變數時,預設會選用距離inner class最近的階層,也就是Local的變數
 如果想要使用Field變數,就需要使用到.this.來選用該field

匿名式Anonymous inner class
與Local inner class一樣
其實Anonymous inner class與Local inner class的性質是一樣的


從外部使用innerClass的方法:
使用成員式Member inner class的方法
一般Member Classes: new <ClassName>().new <InnerClassName>();
意思就是必須先取得的實體,再用其new來取得實體
Static Classes: new <ClassName>.<StaticInnerClassName>();
由於Static類別隨時可以取得,因此直接指名取得實體即可

使用區域式Local inner class的方法
無直接取用方法,僅可能透過所屬method回傳,限制也很多,用途也不大,幾乎不這樣使用

㊟1: 為什麼必須標記為final才可以使用?
這個說法我看過2個版本,不過後來經過查證,其中有個說法是錯的…真相只有一個!…咳咳
先說一下錯的版本好了,在JAVA全方位學習這本書中有提到關於這個問題的解釋:因為全域變數會自動給定初始值,而區域變數不會,而編譯器為了避免錯誤出現,限制使用者在區域變數上標記final,來確保變數有值(標上final的變數必須給定值)。雖然聽起來很合理,不過卻不是這個原因 ( ̄︶ ̄)>
正確的版本出現在caterpillar大大的網站中,後來去JAVA英文網站查詢後驗證無誤,解釋應該是這樣的:
Local inner class所在的Method回傳值(return)後,Method中的變數將會被銷毀,因此在Method中,被Local inner class所用到的變數會被複製一份來使用,此時,如果該變數不是final,則複製的變數就可能因為更改而不同步,造成錯亂,因此Local inner class所用到的local variables必須標記為final。
另外,匿名式Anonymous inner class所用到的local variables也必須須標記為final,雖然規定都一樣,但是原因並不同。這裡是因為AIC在實體化時,會將使用到的local variables直接複製並且生成為自己的private變數,同樣的,出現拷貝時,就會有同步的問題,因此該變數也必須被標記為final。

沒有留言: