34

举个例子:

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 不允许在默认接口方法上使用访问修饰符?为什么它们不能被子类保护/私有并可能被提升(类似于扩展父类的类如何为被覆盖的方法使用更可见的修饰符)?

一个常见的解决方案是转移到一个抽象类,但是在我的具体情况下,我有一个枚举接口,所以这里不适用。我想它要么被忽略了,要么是因为接口背后的原始想法是它们是可用方法的“合同”,但我想我想输入关于这件事的看法。

我读过“为什么 Java 8 接口方法中不允许使用“final”? ”,其中指出:

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

在我看来,能见度根本不会破坏这方面。

与链接的问题一样,因为它似乎无法关闭,因此在此问题上将不胜感激权威答案,而不是基于意见的答案。

4

1 回答 1

48

正如我们在 Java 8 接口方法中不允许“同步”的原因是什么?为什么 Java 8 接口方法中不允许使用“final”?,扩展接口来定义行为比它最初看起来更微妙。事实证明,每个可能的修饰符都有自己的故事;这不仅仅是盲目地复制课程的工作方式。(事后看来,这至少是显而易见的,因为适用于单继承的 OO 建模工具不会自动适用于多继承。)

让我们从一个显而易见的答案开始:接口一直被限制为只有公共成员,虽然我们在 Java 8 中为接口添加了默认方法和静态方法,但这并不意味着我们必须改变一切只是为了“更像”类。

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

实际上,我们确实考虑过在 Java 8 中使用私有接口方法;由于资源和时间限制,这主要是刚刚从列表底部掉下来的东西。这个功能很可能有一天会重新出现在待办事项列表中。(更新:Java 9 中添加了接口中的私有方法。)

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

所以,简短的回答是,私有接口方法是我们本可以在 8 中完成的,但我们无法完成所有可以完成的工作并且仍然发布,所以它被删除了,但可以回来。

于 2014-12-08T23:58:23.583 回答