Java: 在同一接口的另一个默认方法中调用一个默认方法

Java: invoke a default method in another default method of the same interface

我对 java 8 项功能还很陌生,并尝试了解默认方法。有没有比使用匿名 class 更简单的方法通过同一接口的另一个默认方法调用默认方法? 例如:

public class Frame{

    public static void main(String... args){
        Frame.C c= new Frame.C();
        c.doSomething();
    }

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

    public interface B extends A {
        @Override
        public default void doSomething(){
            System.out.println("B");

            //is there an easier way to invoke that method??
            new B(){}.other();
        }
        default public void other(){
            //doSomething();
            System.out.println("other");
        }
    }

    public static class C implements B{
        @Override 
        public void other(){
            Lambda.B.super.other();
            System.out.println("C");

        }
    }

}

您的意图并不完全清楚,但结构 new B(){}.other(); 暗示了两件事:

  1. 您不想调用重写方法实现
  2. 当在完全不同的实例 (new B(){}) 上调用它时,您调用 other() 的实例显然是不相关的是一个可行的解决方案

这两件事一起意味着您应该改用 static 方法:

public interface B extends A {
    @Override
    public default void doSomething(){
        System.out.println("B");

        otherInB();
    }
    default public void other(){
        otherInB();
    }
    static void otherInB() {
        //doSomething();
        System.out.println("other");
    }
}

由于您的原始方法名称没有包含有用的信息,因此也不可能为该 static 方法建议一个有用的名称。

请注意,Java 9 将在接口中引入对 private 方法的支持,允许将 otherInB() 隐藏到其他 classes,甚至使其成为非 static 以防它必须在同一个实例上使用其他方法。

如果 Java8 中方法的可见性是个问题,请考虑非多态方法的实际位置无关紧要,因此您始终可以使用伴随 class:

public interface B extends A {
    @Override
    public default void doSomething(){
        System.out.println("B");

        BHelper.other();
    }
    default public void other(){
        BHelper.other();
    }
}

/* not public */ class BHelper {
    /* not public */ static void other() {
        //doSomething();
        System.out.println("other");
    }
}

如果实现需要实际的 B 实例,这甚至可以工作,因为您可以将其作为参数传递。

public interface B extends A {
    @Override
    public default void doSomething(){
        System.out.println("B");

        BHelper.other(this);
    }
    default public void other(){
        BHelper.other(this);
    }
}

/* not public */ class BHelper {
    /* not public */ static void other(B instance) {
        //doSomething();
        System.out.println("other");
    }
}