匿名内部类
在Java中调用某个方法时,如果该方法的参数是一个接口类型,除了可以传入一个参数接口实现类,还可以使用匿名内部类实现接口来作为该方法的参数。匿名内部类其实就是没有名称的内部类,在调用包含有接口类型参数的方法时,通常为了简化代码,不会创建一个接口的实现类作为方法参数传入,而是直接通过匿名内部类的形式传入一个接口类型参数,在匿名内部类中直接完成方法的实现。
创建匿名内部类的基本语法格式如下:
new 父接口(){
// 匿名内部类实现部分
}
接下来通过一个案例来学习匿名内部类的定义和使用,如文件1所示。
文件1 Example21.java
1 // 定义动物类接口
2 interface Animal {
3 void shout();
4 }
5 public class Example21{
6 public static void main(String[] args) {
7 String name = "小花";
8 // 定义匿名内部类作为参数传递给animalShout()方法
9 animalShout(new Animal() {
10 // 实现shout()方法
11 public void shout() {
12 // JDK 8开始,局部内部类、匿名内部类可以访问非final的局部变量
13 System.out.println(name+"喵喵...");
14 }
15 });
16 }
17 //定义静态方法animalShout(),接收接口类型参数
18 public static void animalShout(Animal an) {
19 an.shout(); // 调用传入对象an的shout()方法
20 }
21 }
运行结果如图1所示。
图1 运行结果
文件1中,调用animalShout(Animal an)方法时需要一个Animal接口类型的参数,在第9~15行代码就使用了匿名内部类方式实现Animal接口并作为参数传入。
需要注意的是,在文件1中的匿名内部中类访问了局部变量name,而局部变量name并没有使用final修饰符修饰,程序也没有报错,这是JDK 8开始的新特性,允许在局部内部类、匿名内部类中访问非final修饰的局部变量,而在JDK 8之前,局部变量前必须加final修饰符,否则程序编译报错。
对于初学者而言,可能会觉得匿名内部类的写法比较难理解,接下来分两步来介绍匿名内部类的编写,具体如下:
1.在调用animalShout()方法时,在方法的参数位置写上new Animal(){},这相当于创建了一个实例对象,并将对象作为参数传给animalShout()方法。在new Animal()后面有一对大括号,表示创建的对象为Animal的子类实例,该子类是匿名的。具体代码如下所示:
animalShout(new Animal(){});
2.在大括号中编写匿名子类的实现代码,具体如下所示:
animalShout(new Animal()
{
public void shout() {
System.out.println(name+"喵喵...");
}
});
至此便完成了匿名内部类的编写。对于初学者而言不要求完全掌握这种写法,只需尽量理解语法就可以了。