Java中的多态应该都不陌生,这一特性是通过继承父类或者实现父接口来展现的。但是父类或者父接口中定义的方法可能不能满足新需求了。那么很容易想到在原始类中添加方法,但是子类或者实现类都需要变动,显然是相当难维护,为了解决这个问题,Java 8允许在接口内声明静态方法,且允许接口中定义默认方法(default
关键字)。
这里所说的重点就是引进了default
之后,如果某一个具体类 实现了多个具有相同的签名的默认方法之后,Java8 是如何解决冲突的?
public interface A {
default void hello() {
System.out.println("Hello from A");
}
}
public class D implements A{
void hello() {
System.out.println("Hello from D");
}
}
public interface B extends A {
default void hello() {
System.out.println("Hello from B");
}
}
public class C extends D implements B, A {
public static void main(String... args) {
new C().hello();
}
}
由于有继承关系,所以按照规则1先进行查找,C类继承自D,而D含有A接口hello
方法的重写,所以这里打印"Hello from D"
public interface A {
default void hello() {
System.out.println("Hello from A");
}
}
public class D implements A{}
public interface B extends A {
@Override
default void hello() {
System.out.println("Hello from B");
}
}
public class C extends D implements B, A {
public static void main(String... args) {
new C().hello();
}
}
由于有继承关系,所以按照规则1先进行查找,C类继承自D,而D没覆盖hello
方法,所以只能拥有接口A的hello
方法的默认实现,所以C现在拥有了A接口的hello
;规则(2)说如果类或者父类没有对应的方法,那么就应该选择提供了最具体实现的接口中的方法。而这里C实现了B,发现B中更加具体(B中hello
是对A接口hello
的实现),所以程序会再次打印输出“Hello from B”
。
如下所示,这里没有哪个接口的hello更具体
public interface A {
void hello() {
System.out.println("Hello from A");
}
}
public interface B {
void hello() {
System.out.println("Hello from B");
}
}
// 显式消除
public class C implements B, A {
void hello(){
B.super.hello();
}
}
通过在C中显示覆盖hello
指定调用谁的hello
方法。
public interface A{
default void hello(){
System.out.println("Hello from A");
}
}
public interface B extends A { }
public interface C extends A { }
public class D implements B, C {
public static void main(String... args) {
new D().hello();
}
}
其继承关系如下所示:
">
因为继承关系如菱形,所以被称为菱形问题。
只有A声明了一个默认方法。由于这个接口是D的父接口,代码会打印输出“Hello from A”