在方法和作用域內的內部類
阿新 • • 發佈:2018-12-26
目前為止,你所看到的只是內部類典型的用途。通常,如果你要讀寫的程式碼包含了內部類,
那麼它們都是“平凡的”內部類,簡單並且容易理解。然而,內部類的設計卻是相當完備
的。如果你選擇使用內部類,它還有許多難以理解的使用方式。例如,可以在一個方法裡
面或者在任意的作用域內定義內部類。這麼做有兩個理由:
1.如前所示,你實現了某型別的介面,於是可以建立並返回對其的引用。
2.你要解決一個複雜的問題,想建立一個類來輔助你的解決方案,但是又不希望
這個類是公共可用的。
在後面的例子中,先前的程式碼將被修改以用來實現:
1.一個定義在方法中的類
2.一個定義在作用域內的類,此作用域在方法的內部
3.一個實現了介面的匿名類
4. 一個匿名類,擴充套件了有非預設構造器的類
5. 一個匿名類,執行成員初始化
6. 一個匿名類,通過例項初始化實現構造(匿名類不可能有構造器)
雖然 Wrapping 只是一個普通的類,但同時也被其匯出類作為通用“介面”使用。
//: c08:Wrapping.java
publicclass Wrapping {
privateint i;
public Wrapping(int x) { i = x; }
publicint value() {return i; }
}///:~
請注意 Wrapping 的構造器,它需要一個引數,這使得事情更有趣了。
第一個例子展示了在方法的作用域內(而不是在其它類的作用域內)建立一個完整的類。
這被稱作區域性內部類(local inner class):
//: c08:Parcel4.java
// Nesting a class within a method.
publicclass Parcel4 {
public Destination dest(String s) {
class PDestinationimplements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {return label; }
}
returnnew PDestination(s);
}
publicstatic void main(String[] args) {
Parcel4 p = new Parcel4();
Destination d = p.dest("Tanzania");
}
}///:~
與其說 PDestination 類是 Parcel4 的一部分,不如說是 dest()方法的一部分。(要注意
到,你可以在同一個子目錄下的任意類中定義名為 PDestination 的內部類,這並不會有命
名衝突。)所以,在 dest()之外不能訪問 PDestination。注意出現在 return 語句中的向
上轉型——返回的是 Destination 的引用,它是 PDestination 的基類。當然,在 dest()
中定義了內部類 PDestination,並不意味著一旦 dest()方法執行完畢,PDestination 就
不可用了。
下一個例子展示瞭如何在任意的作用域內嵌入一個內部類:
//: c08:Parcel5.java
// Nesting a class within a scope.
publicclass Parcel5 {
privatevoid internalTracking(boolean b) {
if(b) {
class TrackingSlip {
private String id;
TrackingSlip(String s) {
id = s;
}
String getSlip() {return id; }
}
TrackingSlip ts = new TrackingSlip("slip");
String s = ts.getSlip();
}
// Can't use it here! Out of scope:
//! TrackingSlip ts = new TrackingSlip("x");
}
publicvoid track() { internalTracking(true); }
publicstatic void main(String[] args) {
Parcel5 p = new Parcel5();
p.track();
}
}///:~
TrackingSlip 類被嵌入在 if 語句的作用域內,這並不是說它的建立是有條件的,它其實與
別的類一樣都經過編譯了。然而,在定義 TrackingSlip 的作用域之外,它是不可用的。除
那麼它們都是“平凡的”內部類,簡單並且容易理解。然而,內部類的設計卻是相當完備
的。如果你選擇使用內部類,它還有許多難以理解的使用方式。例如,可以在一個方法裡
面或者在任意的作用域內定義內部類。這麼做有兩個理由:
1.如前所示,你實現了某型別的介面,於是可以建立並返回對其的引用。
2.你要解決一個複雜的問題,想建立一個類來輔助你的解決方案,但是又不希望
這個類是公共可用的。
在後面的例子中,先前的程式碼將被修改以用來實現:
1.一個定義在方法中的類
2.一個定義在作用域內的類,此作用域在方法的內部
3.一個實現了介面的匿名類
4. 一個匿名類,擴充套件了有非預設構造器的類
5. 一個匿名類,執行成員初始化
6. 一個匿名類,通過例項初始化實現構造(匿名類不可能有構造器)
雖然 Wrapping 只是一個普通的類,但同時也被其匯出類作為通用“介面”使用。
//: c08:Wrapping.java
publicclass Wrapping {
privateint i;
public Wrapping(int x) { i = x; }
publicint value() {return i; }
}///:~
請注意 Wrapping 的構造器,它需要一個引數,這使得事情更有趣了。
第一個例子展示了在方法的作用域內(而不是在其它類的作用域內)建立一個完整的類。
這被稱作區域性內部類(local inner class):
//: c08:Parcel4.java
// Nesting a class within a method.
publicclass Parcel4 {
public Destination dest(String s) {
class PDestinationimplements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {return label; }
}
returnnew PDestination(s);
}
publicstatic void main(String[] args) {
Parcel4 p = new Parcel4();
Destination d = p.dest("Tanzania");
}
}///:~
與其說 PDestination 類是 Parcel4 的一部分,不如說是 dest()方法的一部分。(要注意
到,你可以在同一個子目錄下的任意類中定義名為 PDestination 的內部類,這並不會有命
名衝突。)所以,在 dest()之外不能訪問 PDestination。注意出現在 return 語句中的向
上轉型——返回的是 Destination 的引用,它是 PDestination 的基類。當然,在 dest()
中定義了內部類 PDestination,並不意味著一旦 dest()方法執行完畢,PDestination 就
不可用了。
下一個例子展示瞭如何在任意的作用域內嵌入一個內部類:
//: c08:Parcel5.java
// Nesting a class within a scope.
publicclass Parcel5 {
privatevoid internalTracking(boolean b) {
if(b) {
class TrackingSlip {
private String id;
TrackingSlip(String s) {
id = s;
}
String getSlip() {return id; }
}
TrackingSlip ts = new TrackingSlip("slip");
String s = ts.getSlip();
}
// Can't use it here! Out of scope:
//! TrackingSlip ts = new TrackingSlip("x");
}
publicvoid track() { internalTracking(true); }
publicstatic void main(String[] args) {
Parcel5 p = new Parcel5();
p.track();
}
}///:~
TrackingSlip 類被嵌入在 if 語句的作用域內,這並不是說它的建立是有條件的,它其實與
別的類一樣都經過編譯了。然而,在定義 TrackingSlip 的作用域之外,它是不可用的。除
此之外,它與普通的類一樣。