第四节 匿名内部类
匿名内部类,也就是没有类名的内部类
1. 基于继承的匿名内部类
语法
new < 匿名内部类要继承的父类的对应构造器 > {
// 匿名内部类的字段和方法
};
- 以上语法既声明了一个内部类也创建了一个匿名内部类对象(若不创建对象则以后无法创建对象,因为其没有类名)
- 在匿名内部类中可以重写父类的方法,以及定义自己的方法和字段,但这些方法和字段只能在匿名内部类中使用,因为无法创建匿名内部类对象引用
匿名内部类的对象的使用是通过多态进行的,用其直接或间接继承的父类的引用指向其对象
所以通过引用只能调用其重写的父类方法,其自己的方法和字段无法被使用,只能自己内部使用
定义匿名内部类
public class CreateNotNameInnerClass {
public static void main(String[] args) {
// 定义继承Student匿名内部类
Student s = new Student() {
@Override
public void sayHello() {
System.out.println("调用匿名内部类!");
}
};
// 通过多态调用重写方法
s.sayHello();
}
}
class Student{
public void sayHello(){
System.out.println("Hello!");
}
}
/*
* 运行结果
* 调用匿名内部类!
*/
2. 基于接口实现的匿名内部类
语法
new < 接口名 > (){
// 匿名内部类字段和方法
}
- 类似基于继承关系的匿名内部类,但
new
后的不是构造器,只是实现接口的一个匿名内部类 - 因为匿名内部类没有名称,所有匿名内部类不能是抽象类,所以必须实现接口中的所有非
default
方法
定义匿名内部类
public class CreateNotNameInnerClass {
public static void main(String[] args) {
// 定义实现Person接口的匿名内部类
Person p = new Person() {
@Override
public void sayHello() {
System.out.println("Calling sayHello() successfully!");
}
@Override
public void run() {
System.out.println("Calling run() successfully!");
}
};
p.sayHello();
p.run();
}
}
interface Person{
void run();
void sayHello();
}
/*
* 运行结果
* Calling sayHello() successfully!
* Calling run() successfully!
*/
匿名内部类的初始化
因为匿名内部类没有类名,所以不能写构造器,但可以使用非静态语句块初始化匿名内部类
public class CreateNotNameInnerClass {
public static void main(String[] args) {
A a = new A() {
// 定义非静态语句初始化块
{
System.out.println("执行非静态语句块");
var = 520;
}
};
System.out.println(a.var);
}
}
abstract class A{
int var;
}
/*
* 运行结果
* 执行非静态语句块
* 520
*/
匿名内部类的使用
实际开发中,很多类只使用一次,不需要创建多个对象的情况下可以使用匿名内部类
下例是使用匿名内部类写比较器
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class TestNotNameInnerClass {
public static void main(String[] args) {
// 创建年龄比较器
// 该类的实例仅仅使用一次
Comparator<Student> cmp = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
};
Set<Student> set = new TreeSet<>(cmp);
set.add(new Student(1001, 18));
set.add(new Student(1000, 15));
set.add(new Student(1048, 23));
set.add(new Student(1451, 12));
System.out.println(set);
}
}
class Student implements Comparable<Student>{
private int id;
private int age;
public Student(int id, int age) {
this.id = id;
this.age = age;
}
public int getAge() {
return this.age;
}
public int getId(){
return this.id;
}
@Override
public int compareTo(Student o) {
// id比较器
return this.id - o.getId();
}
@Override
public String toString() {
return "[ ID: " + this.id + ", Age: " + this.age + " ]";
}
}
/*
* 运行结果(按年龄递增排序)
* [[ ID: 1451, Age: 12 ], [ ID: 1000, Age: 15 ], [ ID: 1001, Age: 18 ], [ ID: 1048, Age: 23 ]]
*/