Java 您能否从继承该接口的接口调用父接口的默认方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24273694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:14:23  来源:igfitidea点击:

Can you call the parent interface's default method from an interface that subclasses that interface?

javajava-8default-methodfunctional-interface

提问by ggb667

In java 8 I have something like this:

在 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();
    }
}

Is there a way to call the default functional interface behavior from implementsB without having to create an anonymous inner class and invoking that?

有没有办法从 implementsB 调用默认功能接口行为而不必创建匿名内部类并调用它?

That has a side effect (calling implementsA's method 2 times), what is desired is a call to the parent's implementation, and then have the childs implementation be able to call the child's default implementation, along with some specialization if needed. As you can see calling the parent's implementation is dead easy, but I don't see a way to avoid re-writing the default implementation unless I add a layer of indirection to the class that implements the child interface, and no way to enforce that.

这有一个副作用(调用 implementsA 的方法 2 次),需要的是调用父级的实现,然后让子级的实现能够调用子级的默认实现,并在需要时进行一些特殊化。正如您所看到的,调用父类的实现非常简单,但我没有看到避免重写默认实现的方法,除非我向实现子接口的类添加了一个间接层,并且没有办法强制执行.

For instance if A unlocked or provided access to a resource say a database, and B unlocks a second resource (another database), I see no way to make code unlock A and then B enforcing this contract through the use of Functional Interfaces, requiring that A and B be called. One level deep you can do it, but N levels deep looks like it's not possible.

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

I intended to use lambdas to avoid making expensive calls but to enforce a semantic order of operations on users of my library.

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

This question is notquite the same as "Explicitly calling a default method in Java", as this question is about interfaces N levels deep, not just calling a parent interfaces default method.

这个问题是完全一样“显式调用Java中的默认方法”,因为这个问题是关于界面N级深,不只是调用父接口的默认方法。

采纳答案by Holger

You can invoke an inherited interface defaultmethod using InterfaceName.super. The rules are the same as for other supermethod invocations: You can invoke the inherited method that you have overridden, but you can't directly invoke the method which the inherited method might have overridden. E.g.

您可以使用 调用继承的interface default方法InterfaceName.super。规则与其他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!
    }
}

But if each overriding method invokes its super method you have a chain of invocations. However, keep in mind that we are talking about interfaces. An implementation can always override a default method without invoking superat all.

但是如果每个覆盖方法都调用它的超级方法,你就有了一个调用链。但是,请记住,我们正在谈论接口。一个实现总是可以覆盖一个默认方法而super根本不调用。