在Java中显式调用默认方法

yzxexxkh  于 2023-04-04  发布在  Java
关注(0)|答案(7)|浏览(332)

Java 8引入了default methods来提供扩展接口的能力,而无需修改现有的实现。
我想知道,当一个方法被重写或者由于不同接口中的冲突默认实现而不可用时,是否可以显式调用该方法的默认实现。

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()

carvr3hs

carvr3hs1#

根据this article,您可以使用以下命令访问接口A中的默认方法

A.super.foo();

这可以如下使用(假设接口AC都有默认方法foo()

public class ChildClass implements A, C {
    @Override    
    public void foo() {
       //you could completely override the default implementations
       doSomethingElse();
       //or manage conflicts between the same method foo() in both A and C
       A.super.foo();
    }
    public void bah() {
       A.super.foo(); //original foo() from A accessed
       C.super.foo(); //original foo() from C accessed
    }
}

AC都可以有.foo()方法,并且可以选择特定的默认实现,或者可以使用一个(或两个)作为新foo()方法的一部分。您也可以使用相同的语法来访问实现类中其他方法的默认版本。
方法调用语法的正式描述可以在JLS的第15章中找到。

waxmsbnn

waxmsbnn2#

这个答案主要是为来自问题45047550的用户编写的,该问题已关闭。
Java 8接口引入了多重继承的一些方面。默认方法有一个实现的函数体。要从超类调用方法,可以使用关键字super,但如果你想用超接口来实现,则需要显式命名它。

class ParentClass {
    public void hello() {
        System.out.println("Hello ParentClass!");
    }
}

interface InterfaceFoo {
    public default void hello() {
        System.out.println("Hello InterfaceFoo!");
    }
}

interface InterfaceBar {
    public default void hello() {
        System.out.println("Hello InterfaceBar!");
    }
}

public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
    public void hello() {
        super.hello(); // (note: ParentClass.super could not be used)
        InterfaceFoo.super.hello();
        InterfaceBar.super.hello();
    }
    
    public static void main(String[] args) {
        new Example().hello();
    }
}

输出:

你好家长班!
你好InterfaceFoo!
你好InterfaceBar!

q5iwbnjs

q5iwbnjs3#

下面的代码应该可以工作。

public class B implements A {
    @Override
    public void foo() {
        System.out.println("B.foo");
    }

    void aFoo() {
        A.super.foo();
    }

    public static void main(String[] args) {
        B b = new B();
        b.foo();
        b.aFoo();
    }
}

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

输出:

B.foo
A.foo
ni65a41a

ni65a41a4#

你不需要覆盖接口的默认方法。只要像下面这样调用它:

public class B implements A {

    @Override
    public void foo() {
        System.out.println("B.foo");
    }

    public void afoo() {
        A.super.foo();
    }

    public static void main(String[] args) {
       B b=new B();
       b.afoo();
    }
}

输出:

A.foo

ukqbszuj

ukqbszuj5#

这取决于你的选择是否要覆盖接口的默认方法。因为默认方法类似于类的示例方法,可以直接在实现类对象上调用。(简而言之,接口的默认方法由实现类继承)

hsgswve4

hsgswve46#

考虑以下示例:

interface I{
    default void print(){
    System.out.println("Interface");
    }
}

abstract class Abs{
    public void print(){
        System.out.println("Abstract");
    }

}

public class Test extends Abs implements I{

    public static void main(String[] args) throws ExecutionException, InterruptedException 
    {

        Test t = new Test();
        t.print();// calls Abstract's print method and How to call interface's defaut method?
     }
}
wb1gzix0

wb1gzix07#

调用Java8函数接口的默认方法

@Functional Interface
interface Process {
   String preInit();
   default String postInit() {
       return "PostInit";
   }
}

public class ProcessImpl {
  Process process = () -> ("PreInit");
  String preInit = process.preInit();
  String postInit = process.postInit(); // Calling default method "postInit()" from functional interface
  System.out.println(preInit);
  System.out.println(postInit);
}

Output:
PreInit
PostInit

相关问题