网络中的说法
关于java8接口中默认方法的使用
8在接口中引入了默认方法,通过在方法前加上default关键字就可以在接口中写方法的默认实现,有点类似于C++中的多继承,但是当多个接口或父类中有相同签名的方法时,会引发一些问题,经过实验得出如下结论:
1.当继承的父类和实现的接口中有相同签名的方法时,优先使用父类的方法。
2.当接口的父接口中也有同样的默认方法时,就近原则调用子接口的方法。
3.当实现的多个接口中有相同签名的方法时,必须在实现类中通过重写方法解决冲突问题,否者无法通过编译,在重写的方法中可以通过 接口名.super.方法名(); 的方式显示调用需要的方法。
java核心技术的说法
接口中解决默认方法冲突
如果先在一个接口中将一个方法定义为默认方法,然后又在超类或者另一个接口中定义了同样的方法,那么同时实现这两个接口的类或者既继承了超类又实现了接口的类就会发生冲突。但Java提供相应的规则:
1.超类优先。如果超类提供一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
2.接口冲突。如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型相同的方法,就必须解决冲突。
例子
1.假设Person是一个类(有getName方法),Named是一个接口
interface Named{
default String getName(){
return getClass().getName()
}
}
有一个类Student继承了Person和实现了Named接口:
class Student extends Person implements Named{…}
在这种情况下,只会考虑超类方法,接口的所有默认方法都会被忽略。接口可添加默认方法在Java SE 8中才有,使用“类优先”原则可以确保Java SE 7的兼容性,如果为一个接口添加默认方法,这对于有这个默认方法之前能正常工作的代码不会有任何影响。
2.假设Person是一个接口(默认实现了getName方法),Named依旧是一个接口,类Student实现了这两个接口:
class Student implements Person,Named{…}
类会继承Person和Named接口中提供的两个不一致的getName方法,并不是从中选择一个,这样Java编译器就会报告一个错误,我们需要解决这个二义性。只需要在Student类中提供一个getName方法,在这个方法中,可以选择两个冲突方法中的一个:
class Student implement Person,Named{
public String getName(){
return Person.super.getName();
}
}
现在假设Named接口没有为getName提供默认实现:
interface Named
{
String getName();
}
Students类会从Person接口继承默认方法吗?这好像挺有道理,不过,Java设计者更强调一致性。两个接口如何冲突并不重要。如果至少有一个接口提供了一个实现,编译器就会报告错误,而程序员就必须解决这个二义性。