当前位置: 首页 > 面试题库 >

您可以从子类接口的接口调用父接口的默认方法吗?

濮阳宁
2023-03-14
问题内容

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

这会有副作用(两次调用ImplementsA的方法),需要调用父级的实现,然后让子级的实现能够调用子级的默认实现,并在需要时进行一些专门化。如您所见,调用父级的实现非常简单,但是我看不到一种避免重写默认实现的方法,除非我在实现子接口的类上添加了间接层,并且没有办法实现。

例如,如果A解锁或提供了对资源的访问权(例如数据库),而B解锁了第二个资源(另一个数据库),则我看不到任何方法使代码解锁A,然后B通过使用功能接口来强制执行此合同。
A和B被称为。 您可以执行一个深层次的操作,但是看起来不可能达到N级。

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

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


问题答案:

您可以使用调用继承的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!
    }
}

但是,如果每个重写方法都调用其超级方法,则您会有一系列调用。但是,请记住,我们在谈论接口。一个实现可以始终覆盖默认方法而无需调用super



 类似资料:
  • 在Java8中,我有如下内容: 例如,如果A解锁或提供了对一个资源(比如数据库)的访问,而B解锁了第二个资源(另一个数据库),我认为没有办法使代码解锁A,然后B通过使用函数接口强制执行这个契约,要求调用A和B。一层深的你可以做到,但N层深的看起来就不可能了。 我打算使用lambdas来避免进行昂贵的调用,但要对我的库的用户执行语义操作顺序。 这个问题与“在Java中显式调用默认方法”并不完全相同,

  • 问题内容: 向所有Java专家致敬! 从Java8开始,我们可以在接口中使用默认实现(是的!)。但是,当您想从默认方法登录时会出现问题。 我有种感觉,每次我想在默认方法中记录某些内容时都调用.getLogger()是不明智的。 是的,可以在接口中定义静态变量-但这对于接口而言不是一个好习惯,而且+暴露了记录器(必须是公开的)。 我目前的解决方案: LogHolder仍然对所有人可见,这实际上没有任

  • 问题内容: 考虑以下情况, 在上面的例子中我得到以下输出这是 相当 期待。 我一直在阅读有关默认方法的信息, 尤其是 关于扩展包含默认方法的接口的信息 2 第二子弹:重新声明的默认方法,这使得它的抽象。 在上面的示例中,我有两个接口的默认方法具有相同的名称,并且当我实现这两个接口时,我只能实现对的引用。 我对此几乎没有疑问, 我怎样才能 到达 的方法 和 如果我不能比,为什么? 没有这种行为从本质

  • 我试图使用以下代码理解Java接口中的默认方法,但我无法编译它: 编译器生成了以下输出: 我无法理解这些错误。我如何更正代码中的问题?

  • 我想通过创建一个具体实现类的对象来执行接口中默认方法的定义体,该对象也覆盖了该方法。无论我是直接创建具体实现类的对象,还是通过动态绑定/多态,实现类中定义/重写的主体都只是得到执行。请看下面的代码 我想知道如何在控制台内部界面银行打印以下内容--loan()

  • 假设我有两个类,和: 在将实例化为之后,我可以像那样调用的方法。我还可以使的方法使用调用的方法。但如果是一个接口会怎样: 有什么方法可以让的方法调用的方法吗?