为什么使用内部类
- 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据。
- 内部类可以包中其它类隐藏起来。
- 当想要定义一个回调函数且不想编写大量代码时,使用匿名(anonymous)内部类比较便捷。
嵌套是一种类之间的关系,而不是对象之间的关系。
嵌套类的好处:
- 命名控制;
- 访问控制;
内部类是由外部类的方法构造。
内部类既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域。
@Data @AllArgsConstructor @NoArgsConstructor public class TalkingClock { private int interval; private boolean beep; public class TimerPrinter implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("The time is: " + new Date()); if(beep){//相当于outer.beep Toolkit.getDefaultToolkit().beep(); } } } }
外围类的引用在构造器中设置
public TimerPrinter(TalkingClock clock){ outer = clock; }
outer不是Java中的关键字
6.4.2内部类的特殊语法规则
使用外围类引用内部类
表达式:OuterClass.thisouterObject.new InnerClass(construction parameters)
例如
ActionListener listener = this.new TimePrinter();
在外围类的作用域之外,可以这样引用内部类:
OuterClass.InnerClass
内部类可以直接使用外部类的域(使用beep,也可以使用OuterClass.this.beep)
内部类所有声明的静态域都必须是final。
内部类不能有static方法。
6.4.3内部类是否有用、必要和安全
内部类时一种编译器现象与虚拟机无关。
内部类可以访问外部类的私有数据。
6.4.4局部内部类
局部类不能使用public或private访问符进行声明。
局部类的优势时对外部世界可以完全隐藏起来。即使外部类中的其它方法也不能访问它。public void start(){ class TimePrinter implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("哈哈哈"+ new Date()); if (TalkingClock.this.beep) Toolkit.getDefaultToolkit().beep(); } } ActionListener actionListener = new TimePrinter(); Timer t = new Timer(interval,actionListener); t.start(); }
6.4.5由外部方法访问变量
局部类不仅可以访问包含他们的外部类,还可以访问局部变量(但是局部变量必须为final)。
public void start(int interval,boolean beep){ class TimePrinter implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("哈哈哈"+ new Date()); if (TalkingClock.this.beep) Toolkit.getDefaultToolkit().beep(); } } ActionListener actionListener = new TimePrinter(); Timer t = new Timer(interval,actionListener); t.start(); }
6.4.6匿名内部类
由于构造器的名字必须与类名相同,而匿名类没有类名,所以匿名类不能有构造器。取而代之的是将构造器参数传递给超类(superclass)构造器。尤其是在内部类实现接口的时候,不能有任何构造参数。
6.4.7静态内部类
有时候,内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类的对象。为此,可以将内部类声明为static,以便取消产生的引用。
@Data @NoArgsConstructor @AllArgsConstructor public class Pair { private double first; private double second; public static void main(String[] args) { double [] d = {34.5d,7.34d,3432.76d,999.333d}; Pair pair = ArrayAlg.minmax(d); System.out.println(pair.getFirst()); System.out.println(pair.getSecond()); } } class ArrayAlg{ 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); } }
只有内部类可以声明为static。