Java 8 对接口设计了默认方法和静态方法
默认方法
接口的默认方法类似于抽象类中的抽象方法
接口是否可以取代抽象类
不可以,原因有以下几点:
- 接口的变量只能是常量(
public static final
)。 - 接口的方法修饰符只能是
public
。 - 接口不存在构造函数,抽象类中虽然有构造函数,但仍然不能实例化。
实际开发中有哪些例子是只能用抽象类来实现的?
多继承的问题
如果一个类实现了两个接口,两个接口里面有同样的方法,而且都有自己的默认实现。当我调用这个类此方法的时候,到底调用的是哪个默认方法?
当一个类实现了多个接口,而这些接口中存在两个或两个以上方法签名相同的默认方法时,这被认为是冲突的。解决冲突需要遵守几个原则:
- 类或父类中显式声明的方法,其优先级高于所有的默认方法
- 如果1规则失效,则选择与当前类距离最近的具有具体实现的默认方法
- 如果2规则也失效,则需要显式指定接口
设计目的
减少第三方工具类的创建
例如在 List 等集合接口中都有一些默认方法,List 接口中默认提供 replaceAll(UnaryOperator)、sort(Comparator)、spliterator() 等默认方法,这些方法在接口内部创建,避免了为了这些方法而专门去创建相应的工具类。
可以避免为了复用而创建基类
在 Java 8 之前可能需要创建一个基类来实现代码复用,而默认方法的出现,可以不必去创建基类。
更好地支持集合的 API 在 lambda 表达式中应用
举个例子,为了在 Java 8 中为了扩展 Iterator 接口的 forEach() 方法,如果我们不创建默认方法,那么的话势必会带来和接口的演化类似的问题,换句话说这一点实际上与为了接口演化类似。