6.3内部类
作者:互联网
6.3内部类
使用内部类的原因
1.内部类可以对同一个包的其他类隐藏。
2.内部类方法可以访问定义这个类作用域中的数据,包括原本私有的数据。
6.3.1使用内部类访问对象状态
内部类既可以访问自身的数据域,也可以访问创建它的外围类的数据,
这是因为内部类的对象总有一个隐式引用,它指向创建它的外部类对象。
// 外围类的引用在构造器中设置。
//编译器修改了所有的内部类的构造器,添加一个外围类引用的参数。
//因为TimePrinter内部类没有定义构造器,所以编译器为这个类生成了一个默认的构造器
public TimePrinter(TalkingClock clock) {
outer = clock;
}
package innerClass;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Instant;
import javax.swing.*;
public class InnerClassTest {
public static void main(String[] args) {
TalkingClock clock = new TalkingClock(1000, true);
clock.start();
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit(0);
}
/**
* 定义一个内部类
*/
static class TalkingClock {
private int interval;
private boolean beep;
public TalkingClock(int interval, boolean beep) {
this.interval = interval;
this.beep = beep;
}
/**
* start方法
*/
public void start() {
// 当在start方法中创建了TimePrinter
// ActionListener listener = new TimePrinter(this);
ActionListener listener = new TimePrinter();
Timer timer = new Timer(interval, listener);
timer.start();
}
/**
* 定义内部类
*/
public class TimePrinter implements ActionListener {
// 外围类的引用在构造器中设置。
//编译器修改了所有的内部类的构造器,添加一个外围类引用的参数。
//因为TimePrinter内部类没有定义构造器,所以编译器为这个类生成了一个默认的构造器
/* public TimePrinter(TalkingClock clock) {
outer = clock;
}*/
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("At the tone, the time is" + Instant.ofEpochMilli(e.getWhen()));
//内部类既可以访问自身的数据域,也可以访问创建它的外围类的数据,
//这是因为内部类的对象总有一个隐式引用,它指向创建它的外部类对象。
// if(outer.beep){...}
if (beep) {
Toolkit.getDefaultToolkit().beep();
}
}
}
}
}
6.3.2 内部类的特殊语法规则
1.使用外围类引用的正规语法
OuterClass.this 表示外围类引用。例如:
if (OuterClass.this.beep) {
Toolkit.getDefaultToolkit().beep();
}
2.编写内部对象的构造器
outerObject.new.InnerClass(construction parameters)。例如:
ActionListener listener = this.new TimePrinter();
最新构造的Time Printer对象的外围类引用被设置为创建内部类对象方法中的this引用。
一般来说,this是多余的,但是这样可以通过显式地命名将外围类引用设置为其他对象。
6.3.3 内部类是否有用、必要、安全
6.3.4 匿名内部类
使用匿名内部类实现事件监听器和其他回调。如今最好用的还是lambda表达式
6.5代理
利用代理可以在运行时创建实现了一组给定接口的新类。
只有在编译时期无法确定需要实现哪个接口时才有必要使用代理。
标签:内部,TimePrinter,beep,6.3,引用,public 来源: https://blog.csdn.net/qq_41479053/article/details/121365844