Java 8:默认方法解析规则

随着Java 8中默认方法的引入,一个类现在可以从多个位置(例如另一个类或接口)继承相同的方法。 在这种情况下,可以使用以下规则来确定选择哪种方法:

  1. 类或超类方法声明始终优先于默认方法
  2. 否则,将使用具有最具体的默认提供接口的方法
  3. 最后,如果方法同样特定,则会出现编译器错误,并且您将被迫显式覆盖该方法并指定您的类应调用的方法

让我们看一些示例并应用这些规则。

范例1:

以下代码显示什么?

public interface A {
  default void name() {
    System.out.println("A");
  }
}

public interface B {
  default void name() {
    System.out.println("B");
  }
}

public class C implements A {
  @Override
  public void name() {
    System.out.println("C");
  }
}

public class D extends C implements A, B {
  public static void main(final String... args) {
    new D().name();
  }
}

答案 :C

这是因为,如规则1所述,超类Cname()方法声明优先于AB的默认方法声明。

范例2:

以下代码显示什么?

public interface A {
  default void name() {
    System.out.println("A");
  }
}

public interface B extends A {
  @Override
  default void name() {
    System.out.println("B");
  }
}

public class C implements A {}

public class D extends C implements A, B {
  public static void main(final String... args) {
    new D().name();
  }
}

答案 :B

不同于前面的例子, C不覆盖name()但由于它实现A ,它具有从默认方法A 。 根据规则2,如果类或超类中没有方法,则选择最特定的默认提供接口。 因为B扩展了A ,所以它更加具体,因此打印了“ B”。

范例3:

以下代码显示什么?

public interface A {
  default void name() {
    System.out.println("A");
  }
}

public interface B {
  default void name() {
    System.out.println("B");
  }
}

public class D implements A, B {
  public static void main(final String... args) {
    new D().name();
  }
}

:编译器错误! Duplicate default methods named name with the parameters () and () are inherited from the types B and A

在此示例中,没有更多特定的默认提供接口可供选择,因此编译器将引发错误。 要解决该错误,您需要显式覆盖D的方法,并指定要D使用的方法声明。 例如,如果要使用B

class D implements A, B {
  @Override
  public void name() {
    B.super.name();
  }
}

范例4:

以下代码显示什么?

public interface A {
  default void name() {
    System.out.println("A");
  }
}

public interface B extends A {}

public interface C extends A {}

public class D implements B, C {
  public static void main(final String... args) {
    new D().name();
  }
}

:A

子接口BC并未覆盖该方法,因此实际上只有A的方法可供选择。 附带说明一下,如果BC (但不是全部)都覆盖了该方法,则将应用规则2。 顺便说一句,这是钻石问题

翻译自: https://www.javacodegeeks.com/2016/06/java-8-default-method-resolution-rules.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值