一页书

你永远不会过度准备

接口的默认方法和静态方法

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 "我是静态方法"; 
    } 
}
  1. 默认方法通过实例调用,静态方法通过接口名调用。
  2. 默认方法可以被继承,实现类可以直接使用接口默认方法,也可以重写接口默认方法。
  3. 静态方法不能被继承,实现类不能重写接口静态方法,只能使用接口名调用。

由于JVM上的默认方法的实现在字节码层面提供了支持,因此效率非常高。默认方法允许在不打破现有继承体系的基础上改进接口。该特性在官方库中的应用是:给java.util.Collection接口添加新方法,如stream()、parallelStream()、forEach()和removeIf()等等。

尽管默认方法有这么多好处,但在实际开发中应该谨慎使用:在复杂的继承体系中,默认方法可能引起歧义和编译错误。如果你想了解更多细节,可以参考 官方文档

0%