在Java程序中,如果我们希望在调用某方法时,传入一个某个接口类型或者某个抽象类类型的引用变量作为参数,而这个引用变量的应用场合通常只有这一个地方,并且只运用一次,那么我们可以考虑创建匿名内部类。
以如下代码为例:
/**
* 创建匿名内部类。
* Created by Administrator on 2015/2/5 0005.
*/
//定义JobsApple接口,包含两个抽象方法
interface JobsApple{
public double getPrice();
public String getName();
}
//定义RedApple抽象类,包含构造器,实例成员变量,抽象方法
abstract class RedApple{
public String name;
public double price;
public RedApple(){
}
public RedApple(String name,double price){
System.out.println("调用RedApple构造器。。。");
this.name = name;
this.price = price;
}
public abstract String getName();
public abstract double getPrice();
}
public class AnonymousTest {
//定义方法,传入一个Product类型的引用变量作为参数并调用其方法
public void test(JobsApple jp){
System.out.println("买了" + jp.getName() + ",花了" + jp.getPrice() + "元人民币。");
}
public void test(RedApple ra){
System.out.println("买了" + ra.getName() + ",花了" + ra.getPrice() + "元人民币。");
}
public static void main(String[] args){
AnonymousTest ta = new AnonymousTest();
//创建实现JobsApple接口的匿名内部类,并实现该接口所有的抽象方法
ta.test(new JobsApple() {
@Override
public double getPrice() {
return 5288;
}
@Override
public String getName() {
return "苹果六代";
}
});
//定义两个变量作为参数传入构造器
String name = "苹果六袋";
double price = 288;
//创建实现SweetApple抽象类的匿名内部类,并实现该接口所有的抽象方法
ta.test(new RedApple(name,price) {
@Override
public String getName() {
return name;
}
@Override
public double getPrice() {
return price;
}
});
}
}
输出结果如下:
买了苹果六代,花了5288.0元人民币。
调用RedApple构造器。。。
买了苹果六袋,花了288.0元人民币。
可以看出,test(JobsApple jp)需要一个JobsApple接口类型的引用变量作为参数,我们定义一个匿名内部类,创建实现JobsApple接口类型的对象传入。当我们通过接口来创建匿名内部类时,匿名内部类不能显示的创建构造器,因此接口类型的匿名内部类只能调用无参构造器。而test(RedApple rd)类型的匿名内部类是通过继承父类来创建的,匿名内部类和父类拥有相似的构造器,此处的相似是拥有相同的形参列表。
关于匿名内部类还有如下两条规则:
1、匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类。
2、匿名内部类不能定义构造器。由于匿名内部类内有类名,所以无法定义构造器,但是匿名内部类可以定义初始化块,可以通过初始化块来完成构造器需要完成的事情。如下程序所示:
abstract class Book{
String bookName;
String author;
public abstract String getBookName();
public abstract String getAuthor();
}
public class Demo {
public void test(Book b){
System.out.println(b.getBookName() + "的作者是" + b.getAuthor());
}
public static void main(String[] args){
Demo d = new Demo();
d.test(new Book() {
{
bookName = "三国演义";
author = "罗贯中";
}
@Override
public String getBookName() {
return bookName;
}
@Override
public String getAuthor() {
return author;
}
});
}
}
输出结果:
三国演义的作者是罗贯中