匿名内部类:本身是一个类的定义,同时也是一个对象。
因此其既有类的特征,也有创建对象的特征
1.可以访问外部类的属性(包括私有的)
2.可以添加访问修饰符,因为其就是一个局部变量
3.作用域:仅仅在定义它的方法或代码块中
class Outer { // 外部类
// 匿名内部类
new 类/接口(参数列表) {
类体;
}
}
interface Animal {
public void eat();
}
class Tiger implements Animal {
@Override
public void eat() {
System.out.println("吼吼吼");
}
}
// 在类中创建一个Tiger对象
// 传统方法
class Outer1 {
public void f1() {
// 根据接口,实现Tiger类,通过类创建对象
Tiger tiger = new Tiger();
tiger.eat();
}
}
// 根据匿名对象类实现
class Outer2 {
public void f2() {
// 基于接口,创建匿名对象类
new Animal() {
@Override
public void eat() {
System.out.println("汪汪汪");
}
}
}
}
因此,如果某个类创建后使用一次就不再使用,可以通过匿名对象类实现。
匿名对象类的实现可以基于接口、基于类、基于抽象类。
// 基于接口,实现匿名抽象类
interface IA {
void cry();
}
class Outer {
public void f1() {
// 接口类IA不能直接new创建对象,在这里重写了IA中的cry方法,相当于直接new了IA的实例对象
IA iA = new IA() {
@Override
public void cry() {
System.out.println("汪汪汪");
}
}
// 调用iA的方法
iA.cry(); // 汪汪汪
/* 底层对匿名对象类iA的实现:
class XXX implements IA {
@Override
public void cry() {
System.out.println("汪汪汪");
}
}
*/
// 对于iA对象来说,其编译类型为IA,其运行类型为匿名对象类XXX
// 底层在创建类XXX后,会为其分配类名:Outer$1,并创建Outer$1的实例对象
// 将实例对象的地址返回给iA,所以iA指向的是IA实现类Outer$1的实例对象
// 该匿名对象类Outer$1使用一次后就不再使用,但其创建的对象(iA)可以使用多次
}
}
// 基于类,实现匿名对象类
class Animal {
String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
}
public void sleep() {
System.out.println("呼呼呼....")
}
}
class Outer { // 外部类
private int num;
public void f2() {
// 匿名对象类
Animal animal = new Animal("星期一") {
@Override
public void eat() {
System.out.println("好吃好吃...");
}
}
// 调用匿名对象类的方法
animal.sleep();
/* 底层对匿名对象类的实现:
class XXX extends Animal {
public XXX(String name) {
super(name);
}
@Override
public void eat() {
System.out.println("好吃好吃...");
}
}
*/
// 对于匿名对象类,其编译类型为Animal,其运行类型为匿名对象类XXX
// 在匿名对象类中,可以重写Animal中的方法,也可以不重写
// 同时底层也会为其分配类名:Outer$2
}
}
// 基于抽象类,实现匿名对象类
abstract public class Animal {
abstract public void fly();
}
class Outer {
private int num;
public void f3() {
// 匿名对象类
Animal bird = new Animal {
@Override
public void fly() {
System.out.println("飞飞飞...");
}
}
// 基于抽象类,实现匿名抽象类与基于类,实现匿名抽象类大致相同
// 但是基于抽象类实现匿名抽象类,其抽象方法必须重写;
// 而基于普通类,实现匿名抽象类,其方法不必重写
}
}
匿名对象类的使用:作为形参进行传递
public static void main(String[] args) {
// 调用IBShow方法
IBShow(new IB() {
@Override
public void show() {
System.out.println("show...");
}
}
}
public void IBShow(IB ib) {
ib.show();
}
interface IB() {
public void show();
}