今天看spring源码看到关于spring事件发布ApplicationEventPublisher这一块,看到源码部分是默认方法写的:
package org.springframework.context;
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
this.publishEvent((Object)event);
}
void publishEvent(Object var1);
}
想到可以把默认方法的使用总结一下写出来,毕竟默认方法在我们项目中也是有很多地方可以用的到的。
什么是默认方法?默认方法解决了什么问题?
首先接口在没有默认方法的时候,里面的方法都是没有实现的,需要实现类去继承,但是这时候会有一个问题,就是我有一个接口有很多个实现类,如果我们要修改增加一个属性,那就要所有的实现类都要去实现这个方法,这个工作量一下子就变大了。
举个例子,Java集合框架之前是没有的foreach遍历的,那我现在想加一个foreach的方法,那就要对所有的实现类进行处理。下图是关于ArrayList的一个uml图,光这一个中间就要添加很多实现
这个Collection类的实现和子接口有多少,中间实现差异有多少,这都无法解决。
这时候默认方法出来了,他是一个已经实现的方法,不需要实现类实现的方法,可以就直接用。
下面是Iterable关于foreach的解释,可以说JDK8的默认方法支持是一个进步,而不是简简单单在接口里添加一个default关键词。
默认方法的实际使用
1.扩展框架使用,我们日常肯定不都是简单的一个接口然后一堆实现类,有时候框架封装也是一层套一层,一个实现类也是可以多个实现的形式,这时候default扩展方法就有自己的作用,而且还可以自己来实现。
这里我有一个关于demo小例子的连接
关于接口实现方法:接口,子接口以及实现类
我定义vehicle这个接口,我想在上面添加一个可以自动驾驶的默认方法,我还创建两个子接口继承这个接口。
接口
/**
* @Author: zhangpeng
* @Description:
* @Date: 2022/7/26
*/
public interface Vehicle {
void drive();
default void autoDrive(){
System.out.println(" --------vehicle drive------- ");
}
}
子接口:其中之一
package com.example.test.defaultMethod;
/**
* @Author: zhangpeng
* @Description:
* @Date: 2022/7/26
*/
public interface FuelVehicle extends Vehicle{
@Override
default void autoDrive() {
System.out.println("-------fuel vehicle---------");
}
}
实现类
package com.example.test.defaultMethod;
/**
* @Author: zhangpeng
* @Description:
* @Date: 2022/7/26
*/
public class Hybrid implements ElectricVehicle,FuelVehicle{
@Override
public void drive() {
}
// @Override
// public void autoDrive() {
// ElectricVehicle.super.autoDrive();
// }
@Override
public void autoDrive() {
FuelVehicle.super.autoDrive();
}
// @Override
// public void autoDrive() {
// System.out.println("-------Hybrid Vehicle------");
// }
public static void main(String[] args) {
Hybrid hybrid = new Hybrid();
hybrid.autoDrive();
}
}
在这里我实现了两个接口,关于默认方法autoDrive我可以指定其中一个接口的实现,也可以是自己的实现。
2 扩展接口的功能,有时候我们会遇到合并的方法,可能需要多定义一个接口,这个接口和接口类其他方法差不多,甚至是功能重叠的,可以不必要去定义新接口,利用扩展方法就可以利用接口类现有的接口,弄出新的方法,还不用实现类去单独一个个实现。