你可以从子接口那个接口的接口调用父接口的默认方法吗?

在java 8中我有这样的东西:

package test; public class SimpleFuncInterfaceTest { public static void carryOutWork(AFunctionalInterface sfi){ sfi.doWork(); } public static void main(String[] args) { carryOutWork(() -> System.out.println("Do work in lambda exp impl...")); AImplementor implementsA = new AImplementor(); //carryOutWork(() -> implementsA.doWork()); BImplementor implementsB = new BImplementor(); carryOutWork(() -> implementsB.doWork()); } } @FunctionalInterface interface AFunctionalInterface { public void doWork(); default public void doSomeWork(){ System.out.println("FOO"); } } @FunctionalInterface interface BFunctionalInterface extends AFunctionalInterface { @Override default public void doSomeWork(){ System.out.println("BAR");//Unreachable in same object? } } class AImplementor implements AFunctionalInterface { @Override public void doWork() { doSomeWork(); } } class BImplementor extends AImplementor implements BFunctionalInterface { public void doSomeWork(){ super.doSomeWork(); new BFunctionalInterface(){ @Override public void doWork() { }}.doSomeWork(); System.out.println("WUK WUK"); } @Override public void doWork() { doSomeWork(); } } 

有没有办法从implementsB调用默认的function接口行为,而无需创建匿名内部类并调用它?

这有副作用(调用implementsA的方法2次),所需要的是对父实现的调用,然后让子实现能够调用子的默认实现,以及一些特殊化(如果需要)。 正如你所看到的那样调用父实现很容易,但我没有办法避免重写默认实现,除非我在实现子接口的类中添加了一层间接,并且无法强制执行。

例如,如果A解锁或提供对资源的访问权限说数据库,而B解锁第二个资源(另一个数据库),我认为没有办法使代码解锁A然后B通过使用function接口强制执行此合同,要求A和B被称为。 你可以做到一级深度,但N级深度看起来不可能。

我打算使用lambdas来避免进行昂贵的调用,但是对我的库用户强制执行操作的语义顺序。

这个问题与“在Java中显式调用默认方法” 并不完全相同,因为这个问题是关于N级深度的接口,而不仅仅是调用父接口的默认方法。

您可以使用InterfaceName.super调用inheritance的interface default方法。 规则与其他super方法调用相同:您可以调用已重写的inheritance方法,但不能直接调用inheritance方法可能已覆盖的方法。 例如

 interface A { void foo(); default void toOverride() { System.out.println("A"); } } interface B extends A { default void toOverride() { A.super.toOverride(); System.out.println("B"); } } interface C extends B { default void toOverride() { A.super.toOverride();// does not work B.super.toOverride(); System.out.println("B"); } } class D implements B { public void toOverride() { } public void foo() { D.this.toOverride(); B.super.toOverride(); A.super.toOverride(); // does not work! } } 

但是如果每个重写方法都调用它的super方法,那么你就会有一个调用链。 但是,请记住,我们正在讨论接口。 实现总是可以覆盖默认方法而不需要调用super