内部类
内部类(inner class)是定义在另一个类中的类。
使用内部类的原因:
- 内部类可以对同一个包中的其他类隐藏;
- 内部类的方法可以访问定义这个类的作用域中的数据,包括原本私有的数据。
1. 局部内部类
如果一个内部类,只使用了一次,那么可以在一个方法中局部地定义这个类。
class TalkingClock {
public void start(int interval, boolean beep) {
// TimePrinter 类只在start方法中使用,因此可以在start方法中局部地定义这个类。
class TimePrinter implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("At the tone, the time is "
+ Instant.ofEpochMilli(event.getWhen()));
if (beep) Toolkit.getDefaultToolkit().beep();
}
}
var listener = new TimePrinter();
var timer = new Timer(interval, listener);
timer.start();
}
}
2. 匿名内部类
对于局部内部类,更进一步地,如果只想创建这个类的一个对象,就不需要为类指定名字,这样的类就是匿名内部类(anonymous inner class)。
class TalkingClock {
public void start(int interval, boolean beep) {
// TimePrinter 类实现了ActionListener 接口,可以直接用接口去实例化一个对象,不需要为类指定名字
var listener = new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("At the tone, the time is "
+ Instant.ofEpochMilli(event.getWhen()));
if (beep) Toolkit.getDefaultToolkit().beep();
}
};
var timer = new Timer(interval, listener);
timer.start();
}
}
3. 静态内部类
使用内部类时,如果只是为了把一个类隐藏在另一个类的内部,并不需要内部类有外围类对象的一个引用,那么可以把内部类声明为static,这种类就是静态内部类。
class ArrayAlg {
// Pair是外围类ArrayAlg的静态内部类
public static class Pair {
private double first;
private double second;
public Pair(double f, double s) {
first = f;
second = s;
}
public double getFirst() {
return first;
}
public double getSecond() {
return second;
}
}
public static Pair minmax(double[] values) {
double min = Double.POSITIVE_INFINITY;
double max = Double.NEGATIVE_INFINITY;
for (double v : values) {
if (min > v) min = v;
if (max < v) max = v;
}
return new Pair(min, max);
}
}
Pair是外围类ArrayAlg的静态内部类。可以直接通过ArrayAlg.minmax去调用Pair的minmax方法,而不需要实例化一个ArrayAlg对象来使用这个外围类对象的引用。
public class StaticInnerClassTest {
public static void main(String[] args) {
var values = new double[20];
for (int i = 0; i < values.length; i++){
values[i] = 100 * Math.random();
}
// 可以直接通过ArrayAlg去调用Pair的minmax方法
ArrayAlg.Pair p = ArrayAlg .minmax(values);
System.out.println("min = " + p.getFirst());
System.out.println("max = " + p.getSecond());
}
}