如果假设一个接口是完全抽象的,为什么这段代码有效?

问题描述

您好,我是 Java 新手,我正在 Java 编译器中测试以下代码,但由于我对接口的理解不能有具体方法,但此接口有具体方法和工作原理,您能解释一下为什么吗?和输出

“冲刺!”

interface Run {
    default void walk() {
        System.out.print("Walking and running!");
    }
}
interface Jog {
    default void walk() {
        System.out.print("Walking and jogging!");
    }
}
public class Sprint implements Run,Jog {
    public void walk() {
        System.out.print("Sprinting!");
    }

    public static void main(String[] args) {
        new Sprint().walk();
    }
}

解决方法

不幸的是,有一些低质量的 Java 教程站点(不是命名名称)说 Java 接口是“完全抽象的”;即您不能在接口中包含方法 code。还有很多文章和博客都在说同样的话。 (还有教科书。)

这曾经是真的。 2014 年之前。对于任何 Java 版本来说,这不再是真的了。

在 Java 8 中,该语言被扩展为支持 default 方法。这些是在接口本身中声明/定义的完整(即非隐式抽象)方法。这些 default 方法由实现声明接口的所有类继承,并且可以被覆盖......就像从类继承的方法一样。

这从一个方法在分开设置一个default方法的东西(比方说)一个abstract类是一default方法不能直接指任何实例字段。 default 方法引用 this 状态的唯一方法是通过其他(非默认)方法调用。

有关默认方法的更多信息,请阅读 Oracle Java 教程:

在周围的页面中,有更多(正确的/最新的)关于 Java 中继承如何工作的信息。


在您的例子中,有两个接口(JogRun),这两个声明一个default与方法签名walk()。您的 Sprint 类实现了两个接口,因此 walk() 方法都是(名义上)继承的。这将是模棱两可的……如果不是因为 Sprint 也用自己的声明覆盖了继承的 walk()

所以...当您在 walk() 对象上调用 Sprint 时,您会得到覆盖。