3

我对 java 8 功能非常陌生,并尝试了解默认方法。有没有比使用匿名类更容易通过同一接口的另一个默认方法调用默认方法的方法?例如:

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

        }
    }

}
4

1 回答 1

4

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

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

这两件事一起意味着您应该改用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()到其他类,甚至使其成为非接口static,以防它必须在同一实例上使用其他方法。

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

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

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

…</p>

/* 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);
    }
}

…</p>

/* not public */ class BHelper {
    /* not public */ static void other(B instance) {
        //doSomething();
        System.out.println("other");
    }
}
于 2016-02-25T10:11:23.950 回答