14.1.6 接口的默认方法

引入默认方法的动机在于解决Java中接口所固有的更新困难的问题。在Java中,一旦接口被公开,对该接口进行修改是一件非常困难的事情。如果在新版本中为一个已有的公开接口添加一个新的方法,那么所有实现了该接口的已有类都会出现错误,因为这些类中没有添加这个新方法的实现。接口的默认方法提供了一种简洁的方式来解决这个问题。在接口中,除了方法的声明之外,还可以有方法对应的默认实现。如果该接口的实现类没有实现某个方法,而这个方法由接口提供了默认实现,那么该类会继承接口中的默认实现。在版本更新时,如果向接口中添加了新的方法,可以同时添加对应的默认实现。该接口的已有实现类会继承默认实现,而新的实现类则可以提供新的实现。通过这种方式,既不会对已有的接口实现类造成影响,又可以不断地进行更新。

下面通过一个示例来说明默认方法的作用。代码清单14-8是接口Cursor的已有声明,其中定义了两个方法previous和next,分别用来向前和向后移动指针位置。

代码清单14-8 Cursor接口的已有声明


public interface Cursor{

boolean previous();

boolean next();

}


代码清单14-9是Cursor接口的新版本的声明,其中添加了两个新的方法first和last,用来快速把指针移动到起始或末尾。在first和last方法的声明中,default关键词之后是这两个方法的默认实现。默认实现通过调用已有的previous和next方法来完成。

代码清单14-9 Cursor接口的新版本的声明


public interface Cursor{

boolean previous();

boolean next();

void first()default{

while(previous()){}

}

void last()default{

while(next()){}

}

}


Cursor接口的新的实现类可以提供first和last方法更加高效的实现。

随着lambda表达式的引入,Java中的集合类框架会做出相应的调整,以方便开发人员在进行集合类的相关操作时使用lambda表达式。这就意味着需要对集合类框架中的很多接口进行更新。由于集合类使用广泛,这样的更新势必会造成已有的代码无法运行。通过接口的默认方法,可以很好地解决这个问题。