目前为止,你所看到的只是内部类典型的用途。通常,如果你要读写的代码包含了内部类,
那么它们都是“平凡的”内部类,简单并且容易理解。然而,内部类的设计却是相当完备
的。如果你选择使用内部类,它还有许多难以理解的使用方式。例如,可以在一个方法里
面或者在任意的作用域内定义内部类。这么做有两个理由:
1. 如前所示,你实现了某类型的接口,于是可以创建并返回对其的引用。
2. 你要解决一个复杂的问题,想创建一个类来辅助你的解决方案,但是又不希望
这个类是公共可用的。
在后面的例子中,先前的代码将被修改以用来实现:
1. 一个定义在方法中的类
2. 一个定义在作用域内的类,此作用域在方法的内部
3. 一个实现了接口的匿名类
4. 一个匿名类,扩展了有非缺省构造器的类
5. 一个匿名类,执行成员初始化
6. 一个匿名类,通过实例初始化实现构造(匿名类不可能有构造器)
虽然 Wrapping 只是一个普通的类,但同时也被其导出类作为通用“接口”使用。
//: c08:Wrapping.java
public class Wrapping {
private int i;
public Wrapping(int x) { i = x; }
public int value() { return i; }
} ///:~
请注意 Wrapping 的构造器,它需要一个参数,这使得事情更有趣了。
第一个例子展示了在方法的作用域内(而不是在其它类的作用域内)创建一个完整的类。
这被称作局部内部类(local inner class):
//: c08:Parcel4.java
// Nesting a class within a method.
public class Parcel4 {
public Destination dest(String s) {
class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
public String readLabel() { return label; }
}
return new PDestination(s);
}
public static 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.
public class Parcel5 {
private void 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");
}
public void track() { internalTracking(true); }
public static 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
public class Wrapping {
private int i;
public Wrapping(int x) { i = x; }
public int value() { return i; }
} ///:~
请注意 Wrapping 的构造器,它需要一个参数,这使得事情更有趣了。
第一个例子展示了在方法的作用域内(而不是在其它类的作用域内)创建一个完整的类。
这被称作局部内部类(local inner class):
//: c08:Parcel4.java
// Nesting a class within a method.
public class Parcel4 {
public Destination dest(String s) {
class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
public String readLabel() { return label; }
}
return new PDestination(s);
}
public static 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.
public class Parcel5 {
private void 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");
}
public void track() { internalTracking(true); }
public static void main(String[] args) {
Parcel5 p = new Parcel5();
p.track();
}
} ///:~
TrackingSlip 类被嵌入在 if 语句的作用域内,这并不是说它的创建是有条件的,它其实与
别的类一样都经过编译了。然而,在定义 TrackingSlip 的作用域之外,它是不可用的。除
此之外,它与普通的类一样。