【问题标题】:Java: invoke a default method in another default method of the same interfaceJava:在同一接口的另一个默认方法中调用默认方法
【发布时间】:2016-02-24 20:11:48
【问题描述】:

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

        }
    }

}

【问题讨论】:

  • 所以,不是this.other(),而是您明确想要确切的默认行为?
  • 你为什么希望多态方法是非多态的?
  • 从客户端的角度来看,默认方法是只是普通的老式普通接口方法。默认值仅在声明子类时发挥作用。
  • 如果你希望方法是非多态的,也许它应该是静态方法而不是默认方法。

标签: java java-8 default-method


【解决方案1】:

您的意图并不完全清楚,但 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() 隐藏到其他类,甚至使其成为非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();
    }
}

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

【讨论】:

    猜你喜欢
    • 2019-03-03
    • 2018-06-13
    • 1970-01-01
    • 2017-09-28
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2017-09-25
    相关资源
    最近更新 更多