这个知识点困惑我很久,前几天面试的时候也问到了,没回答出来
首先先说说使用步骤吧
1.有一个接口,且含有一个抽象方法(通常情况我们不会写abstract关键字,冗余的)
2.然后有一个外部类(AnonymousDemo),外部类里面有一个成员方法callInner()
public class Anonymous{
public void callInner(){
}
}
3.匿名内部类在callInner()方法中实现,类似于局部内部类
使用方式就是在callInner()方法中new Dao(接口名),重写Dao接口里面的shhow()方法,并且显示的调用show方法进行回调。
补充:回调方法
-
创建实例与调用方法:
new Dao(){...}
这部分代码负责创建匿名内部类的实例。但是,仅仅创建实例并不会自动执行其中的方法。为了执行show
方法,你需要在实例上显式调用它。 -
执行流程:在匿名内部类后面的
.show()
是对这个刚刚创建的实例的方法调用。如果你没有写.show()
,那么show
方法将不会被执行,匿名内部类实例也就仅仅是被创建而已,不会有任何输出或动作。 -
语法要求:在Java中,方法调用总是需要通过对象引用(即实例)来进行,除非方法是静态的(static)可以直接使用类名调用。在这里,
show
方法不是静态的,因此你需要通过匿名内部类的实例来调用它。
代码实现:
匿名内部类的使用细节
- 匿名内部类的语法比较奇特,请大家注意,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,对前面代码分析可以看出这个特点。
- 可以直接访问外部类的所有成员,包含私有的。
- 不能添加访问修饰符,因为它的地位就是一个局部变量。
- 作用域:仅仅在定义它的方法或代码块中。
- 匿名内部类—>访问—>外部类成员 [访问方式:直接访问]
- 外部其他类—>不能访问—>匿名内部类(因为匿名内部类地位是一个局部变量)
- 如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
匿名内部类的使用目的
有时我们想去调用一个接口/抽象父类的抽象方法,但是又只是调用一次,不存在复用的情况。传统方法我们通常需要创建一个新的类去继承这个抽象父类或者实现这个接口,并且提供抽象方法的实现。这种方式会显得繁琐,通过匿名内部类,我们可以在需要的地方直接创建一个继承自抽象父类或实现接口的子类实例,而无需显式地定义一个新的类。
匿名内部类的注意点
匿名内部类并不是“直接new一个接口或者抽象父类”。实际上,我们是在创建一个新的匿名类的实例,这个匿名类隐式地继承了抽象父类或实现了接口,并且提供了抽象方法的实现。因此,虽然从语法上看起来像是直接new了一个接口或抽象父类,但实际上背后还是进行了类的创建和实例化的过程。
总结:理解了之后其实匿名内部类也没那么复杂,总结一句话无非就是,当我们需要且仅需要使用一次接口/抽象父类 的抽象方法时,就可以考虑使用匿名内部类,并且使用的时候只需要在外部类的方法中进行相应的new Xxx(接口/抽象父类),并且重写方法,在结尾调用回调函数即可。