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

Java:在同一接口的另一个默认方法中调用默认方法,java,java-8,default-method,Java,Java 8,Default Method,我对Java8特性非常陌生,并尝试理解默认方法。使用同一接口的另一个默认方法调用默认方法是否比使用匿名类更简单? 例如: public class Frame{ public static void main(String... args){ Frame.C c= new Frame.C(); c.doSomething(); } public interface A{ public default void doSom

我对Java8特性非常陌生,并尝试理解默认方法。使用同一接口的另一个默认方法调用默认方法是否比使用匿名类更简单? 例如:

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");

        }
    }

}

您的意图并不完全清楚,但是构造
newb(){}.other()意味着两件事:

  • 您不希望调用重写方法实现
  • 在完全不同的实例(
    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");
        }
    }
    
    由于您的原始方法名称没有携带有用的信息,因此也不可能为该
    静态
    方法建议一个有用的名称

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

    如果java 8中的方法的可见性是一个问题,考虑非多态方法的实际位置是不相关的,那么您可以总是使用一个同伴类:

    public interface B extends A {
        @Override
        public default void doSomething(){
            System.out.println("B");
    
            BHelper.other();
        }
        default public void other(){
            BHelper.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);
        }
    }
    


    因此,不是
    this.other()
    ,而是您明确地想要确切的默认行为?为什么希望多态方法是非多态的?从客户机的角度来看,默认方法只是普通的旧接口方法。默认方法只有在声明子类时才起作用。如果您希望该方法是非多态的,可能它应该是静态方法而不是默认方法。
    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");
        }
    }