Java为什么要有default

在Java的接口中,方法默认是抽象的,也就是说只有方法的声明,没有具体的实现代码。然而,从Java 8开始,接口中的方法可以有默认实现。这个特性是为了解决一个问题而引入的,即接口的演化问题。

接口演化问题

在Java之前的版本中,如果要给一个接口添加新的方法,那么所有实现该接口的类都必须实现这个新方法。这样就会导致一个问题,当一个接口被广泛使用时,如果要为接口添加新的方法,那么所有使用该接口的类都必须进行修改。这不仅会导致大量的工作,还可能破坏已有的代码。

为了解决这个问题,Java引入了默认方法。默认方法是指接口中已经实现了的方法,可以直接在接口中提供一个默认的实现,而不需要强制实现该方法的类进行修改。

默认方法的语法

默认方法的语法很简单,只需要在方法声明前加上default关键字即可。下面是一个简单的示例:

public interface MyInterface {
    default void printHello() {
        System.out.println("Hello");
    }
}

上面的代码定义了一个接口MyInterface,其中包含一个默认方法printHello()。如果一个类实现了该接口但没有重写printHello()方法,那么它将直接使用接口中默认的实现。

序列图

下面是一个使用默认方法的示例的序列图:

sequenceDiagram
    participant Interface
    participant Class
    Interface->>Class: 实现
    Class->>Interface: 调用默认方法

默认方法的应用场景

默认方法在接口的演化方面有很大的帮助,它可以避免对已有代码的破坏,并且可以为接口添加新的功能。下面是一些默认方法的应用场景:

向已有接口添加新方法

如果一个接口已经被广泛使用,但需要为该接口添加新的方法,这时可以使用默认方法。这样就不需要修改实现该接口的所有类,只需要在接口中添加默认方法即可。

为接口提供默认实现

默认方法可以为接口提供默认的实现,这样实现接口的类就不需要重复实现相同的代码。例如,可以在Iterable接口中添加一个默认方法来实现迭代功能:

public interface Iterable<T> {
    // ...
    default void forEach(Consumer<? super T> action) {
        for (T t : this) {
            action.accept(t);
        }
    }
    // ...
}

上面的代码中,Iterable接口添加了一个默认方法forEach(),该方法接受一个Consumer对象作为参数,然后对集合中的每个元素执行相应的操作。

总结

默认方法是为了解决接口的演化问题而引入的特性。它可以避免对已有代码的破坏,并且可以为接口添加新的功能。通过默认方法,我们可以向已有接口添加新方法,为接口提供默认的实现,以及在接口中实现一些通用的功能。

默认方法的引入使得接口的设计更加灵活,同时也让我们能够更好地应对接口演化的问题。

通过上面的解释和示例,希望你已经对Java中的默认方法有了更深入的理解。

参考资料:

  • [Java 8 Default Methods](