使用场景:
如上,这时如果子类只会用到一次,那再去特意定义子类就比较费事了,我们就可以用到匿名类进行编写。
匿名类的使用
当存在一个抽象父类如下(普通父类同样适用):
abstract class People {
public abstract void what(); //用在第一种情况
public abstract void eat(); //用在第二种情况
}
第一种情况:
抽象类是不允许实例化的,假设这个时候有一个子类King去继承抽象父类,
我们利用向上转型可以写成People p1=new King();,或者将King变成匿名类。
public class Test {
public static void main(String[] args) {
People p1 = new People() { //匿名类没有名字
private String name = "路飞";
public void what() {
System.out.println(name + "是船长");
}
@Override
public void eat() {
}
};
p1.what(); //通过People对象p1去调用匿名类重写后的方法
}
}
运行结果如下:
第二种情况:
当有很多子类都需要重写并调用同一父类方法时,如果多个子类分别实现就很繁琐。这个就可以写一个传入父类对象的方法。
public void likeEat(People people) {
people.eat();
}
这个时候如果写了子类,就可以分别创建子类对象,再调用重写的方法。如果使用匿名类,如下,就不需要编写多个子类,直接在传入参数时,编写匿名类。
//创建实现类对象
Test test = new Test();
//利用实现类对象调用重写方法
test.likeEat(new People() {
private String name = "索隆";
@Override
public void what() {
}
@Override
public void eat() {
System.out.println(name + "爱喝酒");
}
});
test.likeEat(new People() {
private String name = "弗兰奇";
@Override
public void what() {
}
@Override
public void eat() {
System.out.println(name + "爱喝可乐");
}
});
运行结果:
第三种情况:
有一个接口如下。
public interface IColour {
void colour();
}
在实现类中使用匿名类
IColour p2 = new IColour() {
private String name = "山治";
@Override
public void colour() {
System.out.println(name + "是黄头发");
}
};
p2.colour();
运行结果:
匿名类既可以继承父类,又可以实现接口,但不能同时发生。
注意事项
- 匿名内部类无法编写构造方法
- 匿名内部类中不能使用静态成员
- 匿名内部类无法使用访问修饰符
- 因为编译器无法直接获得类名信息,所以.class文件命名由外部类加&加序号来命名