在java基础中,我们一定听过匿名内部类这个名词,当真正应用到工作中时,又对其理解的马马虎虎。针对我这种马马虎虎的开发者,又来详细回顾基础啦,大佬请绕道🤭
本篇文章将为你解读以下几个问题:
目录
一、什么时匿名内部类?
匿名内部类是指没有指定类名的内部类,当某个类不需要重复使用时就可以把该类定义为匿名内部类。由于匿名内部类没有类名,所以在程序中只能被调用一次。它必须继承或实现一个接口,但不能同时实现多个接口。
二、如何定义匿名内部类?
new 实现接口()| 父类构造器(实参列表){
//匿名内部类的类体部分
}
三、匿名内部类有什么作用?
1.从重构的角度上看,主要是减少一些重复代码。举个栗子:
提出需求:计算一个方法执行的时间,通常我们毫不犹豫的这样写。这样写看起来没什么问题,但是当需求改变,此时我们需要计算其他方法的计算时间时,如果改变下面逻辑代码,其他复制粘贴,会显得代码极其繁琐。
public static void test() {
long start = System.currentTimeMillis();
// 逻辑代码
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
long end = System.currentTimeMillis() - start;
System.out.println(end);
}
为了解决上面的问题,我们可以将逻辑代码抽取成一个接口或一个类传入test。
interface Myservice{
void invoke();
}
那么在不同逻辑代码调用时重写invoke方法即可
public class Timing {
public static void test(Myservice myservice){
long start = System.currentTimeMillis();
myservice.invoke();
long end = System.currentTimeMillis() - start;
System.out.println(end);
}
public static void main(String[] args) {
test(new Myservice() {
@Override
public void invoke() {
// 逻辑代码部分重写
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
});
}
}
如果想让代码看起来更加简洁明了,可使用lambda表达式。但需要注意的是lambda表达式只能替换只有一个抽象方法的接口 ,如何接口中在添加一个invoke1()方法,会出现编译报错。
test(()->{
for (int i=0;i<10;i++){
System.out.println(i);
}
});
如果使用default修饰invoke1()方法,那么就不会报错了。这里引入了另一个知识点,接口中的default方法。参考文章:https://blog.csdn.net/qq_44572962/article/details/115525973
2.你想使用一个类的protected 方法时,但是又不和这个类在同一个包下,你是没办法调用的。这时候匿名类就派上用场了。举个栗子:
package annoymous;
/**
* @ClassName : TestClass
* @Description: TODO
* @Author: lpx
* @CreateDate: 2021/5/17 22:11
*/
public class TestClass {
protected void test(){
System.out.println("test");
}
public static void main(String[] args) {
new TestClass().test();
}
}
package test;
import annoymous.TestClass;
/**
* @ClassName : Test01
* @Description: TODO
* @Author: lpx
* @CreateDate: 2021/5/17 22:13
*/
public class Test01 {
public static void main(String[] args) {
new TestClass(){
void callParentTest(){
super.test();
}
}.callParentTest();
}
}
四、匿名内部类的特性
1、匿名内部类不能有构造器(构造方法),匿名内部类没有类名,无法定义构造器,构造方法的方法名是要与类名一致,但匿名内部类可以定义实例初始化块。
2、匿名内部类不可以是抽象类,java在创建匿名内部类的时候,会立即创建内部类的对象,而抽象类不能创建实例。
综合例子:
大概就总结这些了,边学习边总结,欢迎大家留言哦,一起学习进步 bye~~~❤