为什么Java 8不允许使用非公共默认方法?

时间:2014-12-08 22:46:29

标签: java java-8 default-method

让我们举个例子:

public interface Testerface {

    default public String example() {
        return "Hello";
    }

}

public class Tester implements Testerface {

    @Override
    public String example() {
        return Testerface.super.example() + " world!";
    }


}

public class Internet {

    public static void main(String[] args) {
        System.out.println(new Tester().example());
    }

}

简单地说,这将打印Hello world!。但是说我正在使用Testerface#example的返回值执行其他操作,例如初始化数据文件并返回不应该离开实现类的敏感内部值。为什么Java不允许在默认接口方法上使用访问修饰符?为什么它们不能被保护/私有并且可能被子类提升(类似于扩展父类的类如何为重写方法使用更可见的修饰符)?

一个常见的解决方案是转移到抽象类,但在我的特定情况下,我有一个枚举界面,所以这里不适用。我想它或者被忽视了,或者因为接口背后的原始想法是他们是一个"合同"可用的方法,但我想我想要输入有关这个的内容。

我已阅读" Why is “final” not allowed in Java 8 interface methods?",其中声明:

  

默认方法的基本思想是:它是一个带有默认实现的接口方法,派生类可以提供更具体的实现

对我而言,可见性根本不会破坏这方面。

与链接的问题一样,因为它看起来很难被关闭,这个问题的权威答案,而不是基于意见的答案。

1 个答案:

答案 0 :(得分:41)

正如我们在What is the reason why “synchronized” is not allowed in Java 8 interface methods?Why is "final" not allowed in Java 8 interface methods?中看到的那样,扩展界面以定义行为比首次出现时更加微妙。事实证明,每个可能的修饰语都有自己的故事;它不仅仅是盲目地复制类的工作方式。 (事后看来,这至少是显而易见的,因为用于单继承的OO建模工具不会自动用于多重继承。)

让我们从明显的答案开始:接口总是仅限于公共成员,而我们在Java 8中为接口添加了默认方法和静态方法,而且#&# 39;意思是我们必须改变一切只是为了"更像是"类。

synchronizedfinal不同,这可能是支持默认方法的严重错误,较弱的可访问性(尤其是私有)是需要考虑的合理功能。私有接口方法,无论是静态的还是实例的(请注意,这些不是默认值,因为它们不参与继承)是一个非常明智的工具(虽然它们很容易被非公共帮助程序类模拟。)

我们确实考虑过在Java 8中使用私有接口方法;由于资源和时间限制,这大部分都是从列表底部掉下来的。有一天,这个功能很可能会重新出现在待办事项清单上。

然而,包和受保护的方法比它们看起来更复杂;多重继承的复杂性和protected的真实含义的复杂性将以各种不那么有趣的方式相互作用。所以我不会为此屏住呼吸。

所以,简短的回答是,私有接口方法是我们本可以在8中完成的,但是我们无法完成所有可能已经完成但仍在发布的内容,因此它已被切断,但可能会回来。