【问题标题】:How does "default" (interface) work?“默认”(界面)如何工作?
【发布时间】:2015-10-09 10:44:37
【问题描述】:

为什么这个程序会给出“Class A”的输出?

abstract class A {
      public void abc() {
        System.out.println("Class A");
      }
    }         
    interface B {
      default void abc() {
        System.out.println("Interface B");
      }
    }
    public class Test extends A implements B {
      public static void main(String[] args) {
        Test t = new Test();
        t.abc();
      }
    }

谁能解释一下?

【问题讨论】:

标签: java


【解决方案1】:

虽然抽象类和接口都具有相同的方法,但抽象类方法在运行时选择时具有很高的偏好。

这里是JLS on Method invocation principles

可能没有一种方法是最具体的,因为有两种或多种方法是最具体的。在这种情况下:

如果所有最具体的方法都具有重写等效签名(第 8.4.2 节),则:

如果最具体的方法中恰好有一个是具体的(即非抽象的或默认的),那么它就是最具体的方法。

否则,如果所有最大特定方法都是抽象的或默认的,并且所有最大特定方法的签名具有相同的擦除(第 4.6 节),则在最大特定的子集中任意选择最特定的方法具有最具体返回类型的方法。

在这种情况下,最具体的方法被认为是抽象的。此外,当且仅当在每个最具体方法的 throws 子句中声明了该异常或其擦除时,最具体的方法才被认为抛出一个检查异常。

否则,方法调用不明确,出现编译时错误。

【讨论】:

  • 请举一个例子,其中有两种最大特定的方法
  • @UmeshKushwaha 目前您有两种最具体的方法。 abc() 在超类和你的接口中 B 另一个方法 abc()
  • 语法错误。您是否有任何示例,我们有两种默认方法,但一种更具体
  • @UmeshKushwaha 更新了我的答案。你达到了规范的最后一点:)
【解决方案2】:

当你声明你正在实现一个接口时,就等于说:“我将为这个接口中声明的所有方法做一个实现”。 当你扩展一个抽象类时,你会说:“我将实现这个类中的所有抽象方法并继承所有非抽象方法”。

所以,你继承了定义的方法来满足接口的需要,继承覆盖了接口的默认值。

【讨论】:

    【解决方案3】:

    编辑:我今天学到了一些新东西。抽象方法在运行时选择时具有更高的偏好。

    接口是抽象方法的集合。所以

    System.out.println("Interface B");
    

    语句不被继承。

    System.out.println("Class A");
    

    是在Test t的实例中继承的,因为它是抽象的sand有更高的偏好。

    【讨论】:

    • 不,接口内的默认方法像实例方法一样被继承
    猜你喜欢
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多