首页 文章

在Java中显式调用默认方法

提问于
浏览
175

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

4 回答

  • 13

    您不需要覆盖接口的默认方法 . 只需将其称为如下:

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

    Output:

    A.foo

  • 3

    下面的代码应该有效 .

    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
    
  • 2

    根据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() 方法的一部分 . 您还可以使用相同的语法来访问实现类中其他方法的默认版本 .

    可以在chapter 15 of the JLS中找到方法调用语法的形式描述 .

  • 219

    这个答案主要是针对来自问题45047550的用户而写的 .

    Java 8接口介绍了多重继承的一些方面 . 默认方法具有已实现的函数体 . 要从超类调用方法,可以使用关键字 super ,但是如果要使用超级接口进行此操作,则需要显式命名 .

    class Clazz {
    
        public void foo() {
            System.out.println("Hello Clazz!");
        }
    
    }
    
    interface Interface111 {
    
        default public void foo() {
            System.out.println("Hello Interface111!");
        }
    
    }
    
    interface Interface222 {
    
        default public void foo() {
            System.out.println("Hello Interface222!");
        }
    
    }
    
    public class Example extends Clazz implements Interface111, Interface222 {
    
        public void foo() {
            super.foo(); // (note: Clazz.super is wrong!)
            Interface111.super.foo();
            Interface222.super.foo();
        }
    
        public static void main(String[] args) {
            new Example().foo();
        }
    
    }
    

    Output:

    Hello Clazz!你好Interface111!你好Interface222!

相关问题