Interface in Java 1.8

Java 8 对接口设计了默认方法和静态方法

默认方法

接口的默认方法类似于抽象类中的抽象方法

接口是否可以取代抽象类

不可以,原因有以下几点:

  1. 接口的变量只能是常量(public static final)。
  2. 接口的方法修饰符只能是 public
  3. 接口不存在构造函数,抽象类中虽然有构造函数,但仍然不能实例化。

实际开发中有哪些例子是只能用抽象类来实现的?

多继承的问题

如果一个类实现了两个接口,两个接口里面有同样的方法,而且都有自己的默认实现。当我调用这个类此方法的时候,到底调用的是哪个默认方法?

当一个类实现了多个接口,而这些接口中存在两个或两个以上方法签名相同的默认方法时,这被认为是冲突的。解决冲突需要遵守几个原则:

  1. 类或父类中显式声明的方法,其优先级高于所有的默认方法
  2. 如果1规则失效,则选择与当前类距离最近的具有具体实现的默认方法
  3. 如果2规则也失效,则需要显式指定接口

设计目的

  1. 减少第三方工具类的创建

    例如在 List 等集合接口中都有一些默认方法,List 接口中默认提供 replaceAll(UnaryOperator)、sort(Comparator)、spliterator() 等默认方法,这些方法在接口内部创建,避免了为了这些方法而专门去创建相应的工具类。

  2. 可以避免为了复用而创建基类

    在 Java 8 之前可能需要创建一个基类来实现代码复用,而默认方法的出现,可以不必去创建基类。

更好地支持集合的 API 在 lambda 表达式中应用

举个例子,为了在 Java 8 中为了扩展 Iterator 接口的 forEach() 方法,如果我们不创建默认方法,那么的话势必会带来和接口的演化类似的问题,换句话说这一点实际上与为了接口演化类似。

静态方法