Java声称添加这两种新方法的原因是"确保与为这些接口的旧版本编写的代码的二进制兼容性".
这仅适用于默认方法(不是静态方法),省略了某些上下文.来自兰茨州的Goetz:
默认方法的目的是使接口在初始发布后以兼容的方式进化.
主要目标是允许界面演变,即添加新方法.如果将新方法添加到接口,则实现该接口的现有类将缺少实现,这将是不兼容的.为了兼容,实现必须来自某个地方,因此它是由默认方法提供的.
为什么要扭曲界面原始概念,假设是完全抽象的,以支持现有的架构问题?
Java接口的主要目的是指定任何类都可以实现的契约,而不必改变它在类层次结构中的位置.确实,在Java 8之前,接口纯粹是抽象的.但是,这不是接口的基本属性.即使包含默认方法,其核心接口仍然在实现类上指定合同.实现类可以覆盖默认方法,因此该类仍然可以完全控制其实现.(另请注意,默认方法不能是最终方法.)
除了类扩展多个接口的能力之外,使用抽象类和接口的新版本有什么区别?
类扩展多个接口的能力与接口和抽象类之间的另一个差异密切相关,即接口不能包含状态.这是允许多重继承的主要困难:如果一个超类在一个类的祖先中多次出现,那么这个超类的状态会出现一次还是几次?(这就是所谓的"钻石问题".)
另一个区别是抽象类可以通过使用受保护和包私有访问级别来定义要与子类共享的方法和字段,而不是与调用者共享.接口只能有公共方法.
(在Java 9中,添加了对私有方法的支持.这对于接口的默认或静态方法之间的实现共享很有用.)
最后,接口中的静态方法不会影响类继承,也不是接口契约的一部分.它们仅仅是以更方便的方式组织实用方法的一种方式.例如,接口中静态方法的常见用法是静态工厂方法.如果接口中不允许使用静态方法,则必须将静态工厂方法放在伴随类上.允许接口中的静态方法允许这样的方法与接口本身分组,这样做是合适的.