匿名类是用来创建接口或者抽象类的实例的。

匿名内部类适合创建只需要一次使用的类。创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名类不能重复使用。

匿名内部类不能定义构造器。因为匿名内部类没有类名,所有无法定义构造器。但匿名内部类可以定义初始化块,可以通过实例初始化块来完成构造器需要完成的事情。

定义匿名内部类格式如下:

1
2
3
4
new 实现接口 | 抽象父类构造器(实参列表)
{
    匿名内部类的类体部分
}

最常用的创建匿名内部类的方式是需要创建某个接口类型的对象,如下

1
2
3
4
public interface ProductA {
    public double getPrice();
    public String getName();
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class AnonymousTest {
    public void test(ProductA p) {
        System.out.println("Buy a" + p.getName() + "Cost " + p.getPrice());
    }
    public static void main(String[] args) {
        AnonymousTest ta = new AnonymousTest();
        // 调用 test() 方法时,需要传入一个 Product 参数
        // 此处传入其匿名实现类的实例
        ta.test(new ProductA() {
            @Override
            public double getPrice() {
                return 567.8;
            }

            @Override
            public String getName() {
                return "APG Card";
            }
        });
    }
}

通过继承抽象父类来创建匿名内部类时,匿名内部类将拥有和父类相同形参列表的构造器。看下面一段代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public abstract class Device {
    private String name;
    public abstract double getPrice();
    public Device() {};
    public Device(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class AnonymousInner {
    public void test(Device d) {
        System.out.println("Buy a" + d.getName()+ "Cost" + d.getPrice());
    }
    public static void main(String[] args) {
        AnonymousInner ai = new AnonymousInner();
        // 调用有参数的构造器创建 Device 匿名实现类的对象
        ai.test(new Device("电子显示器") {
            @Override
            public double getPrice() {
                return 67.8;
            }
        });

        // 调用无参数的构造器创建 Device 匿名实现类的对象
        Device d = new Device() {
            // 初始化块
            {
                System.out.println("匿名内部类的初始化块");
            }
            // 实现抽象方法
            @Override
            public double getPrice() {
                return 56.2;
            }
            // 重写父类的实例方法
            public String getName() {
                return "keyboard";
            }
        };
        ai.test(d);
    }
}