Java 8引入了默认方法来提供扩展接口的能力,而不需要修改现有的实现。

我想知道,当方法被覆盖或由于不同接口中的默认实现冲突而不可用时,是否可以显式调用该方法的默认实现。

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

class B implements A {
    @Override
    public void foo() {
        System.out.println("B.foo");
    }
    public void afoo() {
        // how to invoke A.foo() here?
    }
}

考虑到上面的代码,您将如何从类B的方法调用a .foo() ?

Java 8最有用的特性之一是接口上新的默认方法。它们被引入的主要原因有两个(可能还有其他原因):

提供实际的默认实现。例如:Iterator.remove () 允许JDK API的发展。例如:Iterable.forEach ()

从API设计者的角度来看,我希望能够在接口方法上使用其他修饰符,例如final。这在添加方便方法时非常有用,可以防止在实现类时发生“意外”重写:

interface Sender {

    // Convenience method to send an empty message
    default final void send() {
        send(null);
    }

    // Implementations should only implement this method
    void send(String message);
}

如果Sender是一个类,上面已经是常见的做法:

abstract class Sender {

    // Convenience method to send an empty message
    final void send() {
        send(null);
    }

    // Implementations should only implement this method
    abstract void send(String message);
}

现在,default和final显然是相互矛盾的关键字,但default关键字本身并不是严格要求的,所以我假设这种矛盾是故意的,以反映“带有主体的类方法”(只是方法)和“带有主体的接口方法”(默认方法)之间的微妙差异,即我还没有理解的差异。

在某些时候,对接口方法上的修饰符(如static和final)的支持还没有完全开发出来,引用Brian Goetz的话:

另一部分是我们将在多大程度上支持班级建设 接口中的工具,如final方法、私有方法、受保护 方法,静态方法等等。答案是:我们还不知道

显然,从2011年末开始,接口中增加了对静态方法的支持。显然,这为JDK库本身增加了很多价值,例如comparator . compare()。

问题:

final(也是静态final)从来没有出现在Java 8接口中的原因是什么?

Java 8允许在称为default methods的接口中默认实现方法。

我在什么时候使用那种接口默认方法,而不是抽象类(带有抽象方法)之间感到困惑。

那么什么时候应该使用默认方法的接口,什么时候应该使用抽象类(带有抽象方法)?抽象类在这种情况下仍然有用吗?