从 Java 8 开始,接口新增了 default 方法,关于该特性的一个知识点是“default 方法冲突”,共有三种情况,下面分别进行介绍。

父类 + 接口

如果接口中存在一个与父类相同签名的方法,则调用子类的方法时,执行的是父类的逻辑。 default 方法 - 图1如在上图中,父类 Parent 和接口 Named 存在一个相同签名的方法 getName() ,当调用 child.getName() 时,实际执行的是父类的方法。

default + default

如果一个类实现了两个接口,且这两个接口中存在相同的签名的 default 方法,则该实现类必须 override 该方法。 default 方法 - 图2就上图而言 Student 类既可以重写 getName() 方法的实现逻辑,也可以直接选择执行哪个接口的getName() 方法,示例代码如下所示:

  1. class Student implements Person, Named {
  2. @Override
  3. public String getName() {
  4. return Person.super.getName(); // 注意必须是 super 关键字
  5. }
  6. }

default + 非 default

与上一种情况类似,一个类实现了两个接口,且这两个接口中存在相同签名的方法,但一个是 default 方法,另一个不是 default 方法(即一个方法声明),则该实现类也要 override 该方法。 default 方法 - 图3

default 方法的作用

default 方法的一个作用是实现“接口进化”(interface evolution),如对一个已经存在的老旧接口新增一个方法,如果只允许添加方法声明,则所有实现了该接口的历史代码会全部报错,而 default 方法的出现则避免了该问题。

但与此同时,default 方法的出现也带来了争议,有人认为 default 方法违背了接口抽象的原则。