Java8 使用两个新概念对接口进行了增强:默认方法 和 静态方法 。
在JDK8 以前接口中只能有抽象方法。存在以下问题:
如果给接口新增抽象方法,所有实现类都必须重写这个抽象方法。不利于接口的扩展。
JDK 8以前的接口:
interface 接口名 {
静态常量;
抽象方法;
}
JDK 8的接口:
interface 接口名 {
静态常量;
抽象方法;
默认方法;
静态方法;
}
默认方法
格式
interface 接口名 {
修饰符 default 返回值类型 方法名() {
代码;
}
}
默认方法和抽象方法之间的区别在于抽象方法必须要实现,而默认方法不需要。
接口提供的默认方法会被接口的实现类继承或者重写。
查看示例
//Defaulable接口使用关键字default定义了一个默认方法notRequired()
private interface Defaulable {
default String notRequired() {
return "默认方法";
}
}
//DefaultableImpl类实现了这个接口,同时默认继承了这个接口中的默认方法
private static class DefaultableImpl implements Defaulable {
}
//OverridableImpl类也实现了这个接口,但重写了该接口的默认方法,并提供了一个不同的实现
private static class OverridableImpl implements Defaulable {
@Override
public String notRequired() {
return "默认方法-已被重写";
}
}
静态方法
Java 8带来的另一个有趣的特性是在接口中可以定义静态方法
格式
interface 接口名 {
修饰符 static 返回值类型 方法名() {
代码;
}
}
查看示例
private interface staticInterface {
// 定静态方法
static String create() {
return "我是静态方法";
}
}
- 默认方法通过实例调用,静态方法通过接口名调用。
- 默认方法可以被继承,实现类可以直接使用接口默认方法,也可以重写接口默认方法。
- 静态方法不能被继承,实现类不能重写接口静态方法,只能使用接口名调用。
由于JVM上的默认方法的实现在字节码层面提供了支持,因此效率非常高。默认方法允许在不打破现有继承体系的基础上改进接口。该特性在官方库中的应用是:给java.util.Collection接口添加新方法,如stream()、parallelStream()、forEach()和removeIf()等等。
尽管默认方法有这么多好处,但在实际开发中应该谨慎使用:在复杂的继承体系中,默认方法可能引起歧义和编译错误。如果你想了解更多细节,可以参考 官方文档。