Java 8的默认方法试图尝试更进一步简化Java API。不幸的是,这一近的语言扩展带来了一系列复杂的规则,但只有少部分Java开发者意识到这一点。这篇文章告诉你为什么引入默认方法会破坏你的(用户的)代码。
  起初看来,默认方法给Java虚拟机的指令集带来了很多新的特性。终,开发库的人能够在不带来客户端代码的兼容性问题的情况下,升级API。使用默认方法,任何实现库接口的类都自动适应接口引入的默认方法。一旦用户更新了他实现的类,能够很简单使用更有意义的方法来覆盖原有默认方法。更好的是,用户可以在覆盖方法时候,调用接口的默认实现,同时增加业务逻辑。
  到现在为止,一切都是很好。但是,在创建接口的时候增加默认方法可能使得Java代码不兼容。这个从下面的例子可以很容易弄明白。我们假设一个库需要它的一个接口的作为输入:
  interface SimpleInput {
  void foo();
  void bar();
  }
  abstract class SimpleInputAdapter implements SimpleInput {
  @Override
  public void bar() {
  // some default behavior ...
  }
  }
  Java 8之前,类似于上面联合使用一个接口和一个适配器类的方式,是Java程序语言中一种非常常用的设计模式。该适配器通常由库提供者提供,用于节省库的使用者的某些操作。但是,如果采用接口的方式提供,类似允许多重继承了。
  我们进一步假设一个用户使用了如下的适配器:
class MyInput extends SimpleInputAdapter {
@Override
public void foo() {
// do something ...
}
@Override
public void bar() {
super.bar();
// do something additionally ...
}
}
  通过这种实现方式,我们终可以和库进行交互。注意我们是怎样覆盖bar方法,并为默认的实现增加额外的功能的。
  如果将该库移植到Java 8,将会发生什么呢?首先,该库很大可能性会废弃适配器类,而使用默认方法提供该功能。终,该接口的形式类似如下所示:
  interface SimpleInput {
  void foo();
  default void bar() {
  // some default behavior
  }
  }