java - 您可以从子类化该接口(interface)的接口(interface)调用父接口(interface)的默认方法吗?

标签 java java-8 default-method functional-interface

<分区>

在 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 调用默认功能接口(interface)行为而不必创建匿名内部类并调用它?

这有一个副作用(调用 implementsA 的方法 2 次),需要的是调用父级的实现,然后让子级的实现能够调用子级的默认实现,如果需要的话还可以进行一些专门化。如您所见,调用父接口(interface)的实现非常容易,但我看不到避免重写默认实现的方法,除非我向实现子接口(interface)的类添加一个间接层,并且没有办法强制执行它.

例如,如果 A 解锁或提供对资源(例如数据库)的访问权限,而 B 解锁第二个资源(另一个数据库),我认为没有办法让代码解锁 A,然后 B 通过使用功能接口(interface)来执行此契约(Contract),要求调用 A 和 B。 一层深你可以做到,但N层深看起来是不可能的。

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

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

最佳答案

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

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 方法,那么您就有了一个调用链。但是,请记住我们谈论的是接口(interface)。实现始终可以覆盖默认方法,而无需调用 super

关于java - 您可以从子类化该接口(interface)的接口(interface)调用父接口(interface)的默认方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24273694/

相关文章:

java - JSON 类型不匹配或 org.json.jsonecxeption

java - "The import org.springframework cannot be resolved."

java - 并行计算开销

启用 Jacoco 时,具有默认方法的 Java 8 接口(interface)不起作用

java - 使用流组成函数数组

java - 在 Java 中显式调用默认方法

java - 静态实用方法不是这种情况下的最佳方法吗?

java - 使用 Lambda 在 Java 中的对象列表中填充属性

java - 为什么接口(interface)默认方法?

java - Java 8 中 Default 或 Defender 方法的用途