内部类是定义在另一个类中的类。使用内部类有两个原因:
- 内部类可以对同一个包中的其他类隐藏。
- 内部类方法可以访问定义这个类的作用域中的数据,包括原本私有的数据。
1 内部类的语法规则
下面展示一个内部类的实例:
public class TalkingClock
{
private int interval; // 发出通知的时间间隔
private boolean beep; // 开关铃声的标志
public TalkingClock(int interval, boolean beep)
{
this.interval = interval;
this.beep = beep;
}
public void start()
{
TimePrinter listener = new TimePrinter();
Timer timer = new Timer(interval, listener);
timer.start();
}
public class TimePrinter implements ActionListener // 内部类
{
public void actionPerformed(ActionEvent event)
{
System.out.pringln("At the tone, the time is "
+ Instant.ofEpochMilli(event.getWhen()));
if (beep) Toolkit.getDefaultToolkit().beep();
}
}
}
这里的TimePrinter
类位于TalkingClock
类内部,这并不意味着每个TalkingClock
对象都有一个TimePrinter
实例字段,TimePrinter
对象是由TalkingClock
类中的start
方法构造的。
TimePrinter
类中的actionPerformed
方法使用了变量beep
,这个beep
变量实际上是创建TimePrinter
对象的TalkingClock
对象内部的字段。内部类方法可以访问自身的数据字段,也可以访问创建它的外围类对象的数据字段。为此,内部类对象有一个隐式引用,指向创建它的外围类对象。这个引用在内部类的定义中是不可见的。
外围类的引用在构造器中设置。编译器会修改所有的内部类构造器,添加一个对应外围类引用的参数。例如,上面的TimerPrinter
类没有定义构造器,编译器会自动生成一个无参数构造器,并添加一个外围类TalkingClock
类型的参数,代码如下:
public TimePrinter(TalkingClock clock)
{
TalkingClock.this = clock;
}
内部类中对外围类引用的调用是隐式的,可以通过外围类名.this
显式调用。例如上面的TalkingClock.this
就是对外围类引用的显式调用。为了明显区分内部类自身的字段和外围类的字段,可以在内部类方法中显式使用外围类引用。例如&#