从 Java 8 开始,接口新增了 default
方法,关于该特性的一个知识点是“default 方法冲突”,共有三种情况,下面分别进行介绍。
父类 + 接口
如果接口中存在一个与父类相同签名的方法,则调用子类的方法时,执行的是父类的逻辑。
如在上图中,父类
Parent
和接口 Named
存在一个相同签名的方法 getName()
,当调用 child.getName()
时,实际执行的是父类的方法。
default + default
如果一个类实现了两个接口,且这两个接口中存在相同的签名的 default
方法,则该实现类必须 override 该方法。
就上图而言
Student
类既可以重写 getName()
方法的实现逻辑,也可以直接选择执行哪个接口的getName()
方法,示例代码如下所示:
class Student implements Person, Named {
@Override
public String getName() {
return Person.super.getName(); // 注意必须是 super 关键字
}
}
default + 非 default
与上一种情况类似,一个类实现了两个接口,且这两个接口中存在相同签名的方法,但一个是 default
方法,另一个不是 default
方法(即一个方法声明),则该实现类也要 override 该方法。
default 方法的作用
default
方法的一个作用是实现“接口进化”(interface evolution),如对一个已经存在的老旧接口新增一个方法,如果只允许添加方法声明,则所有实现了该接口的历史代码会全部报错,而 default
方法的出现则避免了该问题。
但与此同时,default
方法的出现也带来了争议,有人认为 default
方法违背了接口抽象的原则。