【问题标题】:Why does Java 8 not allow non-public default methods?为什么 Java 8 不允许非公共默认方法?
【发布时间】:2015-02-06 17:23:31
【问题描述】:

举个例子:

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?”,其中指出:

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

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

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

【问题讨论】:

  • 接口中的私有方法是什么意思?
  • 我认为除了“基于意见的答案”之外别无选择。
  • 为您的默认方法想要使用但不会泄露到世界的东西创建一个带有受保护静态方法的私有类。也就是说,这听起来像是糟糕的设计。
  • @njzk2(和 pmorken):您似乎正在遭受想象力的失败。接口中的私有方法可以从接口中的其他方法体(静态或默认)调用,其用途与类中的私有方法完全相同。
  • @njzk2 我认为你迟到了几年:) 几年前,JSR-335 EG 对所有这些问题进行了极其详细的处理。简短的回答:Java总是有多重继承——类型。默认方法添加多重继承行为。我们仍然没有的是多重继承状态,这是最令人讨厌的问题的来源(如钻石。)现在你需要去更新你的语言如何工作的模型......跨度>

标签: java java-8 default-method


【解决方案1】:

正如我们在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 中为接口添加了默认方法和静态方法,但这并不意味着我们有改变一切只是为了“更像”类。

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

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

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

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

【讨论】:

  • 接口上缺少私有方法并结合默认方法不是鼓励开发人员公开mutators吗?
  • 我认为“鼓励”这个词是错误的。它无法阻止。我们本来希望在 8 中将私有方法引入接口,但是在您拥有的时间/资源中可以做的事情是有限度的。
  • 好消息:接口中的私有方法看起来会让 Java 9.
  • 好吧,尽管 Java 8/9 中的所有这些新功能看起来都非常有用和方便,但我认为它有点令人困惑。就我自己的“界面”而言,它的定义更接近于“合同”,而不是它已经变成的样子。我认为在语言中添加一个代表“没有状态的类”而不是增加“接口”的新实体会更漂亮。我想到的是'mixin'之类的东西。
  • @egelev 正如没有人应该感到惊讶的那样,在做出这个决定之前已经进行了广泛的辩论。结论是,创建一个与接口几乎但不完全相同的新的顶级抽象(mixin、trait 等)会更加混乱和侵入性 - 并且可能也无法达到人们的预想- 对 mixin/trait 意味着什么的现有期望。 (说“这是不完美的,你应该做点别的”很容易,但人们也必须更深入地思考替代方案本身是否实际上可能更糟。)
猜你喜欢
  • 2016-09-06
  • 1970-01-01
  • 2013-09-15
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多