Let's take an example:
我们来举个例子:
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());
}
}
Simply enough, this would print Hello world!
. But say I was doing something else with the return value of Testerface#example
, for instance initializing a data file and returning a sensitive internal value that shouldn't leave the implementing class. Why does Java not allow access modifiers on default interface methods? Why can't they be protected/private and potentially elevated by a subclass (similar in how a class that extends a parent class can use a more visible modifier for an overridden method)?
简单地说,这将打印Hello world!。但是我说我正在使用Testerface #example的返回值做其他事情,例如初始化数据文件并返回一个不应离开实现类的敏感内部值。为什么Java不允许在默认接口方法上使用访问修饰符?为什么它们不能被保护/私有并且可能被子类提升(类似于扩展父类的类如何为重写方法使用更可见的修饰符)?
A common solution is moving to an abstract class however in my specific case, I have an interface for enums, so that does not apply here. I imagine it was either overlooked or because the original idea behind interfaces that they are a "contract" of available methods, but I suppose I want input as to what's going on with this.
一个常见的解决方案是转移到抽象类,但在我的特定情况下,我有一个枚举接口,所以这里不适用。我想它或者被忽略了,或者因为接口背后的原始想法是他们是可用方法的“契约”,但我想我想要输入有关这个的内容。
I've read "Why is “final” not allowed in Java 8 interface methods?", which states:
我读过“为什么”最终“在Java 8接口方法中不允许?”,其中指出:
The basic idea of a default method is: it is an interface method with a default implementation, and a derived class can provide a more specific implementation
默认方法的基本思想是:它是具有默认实现的接口方法,派生类可以提供更具体的实现
And it sounds to me like visibility wouldn't break that aspect at all.
在我看来,可见性根本不会破坏这方面。
As with the linked question since it looks like it had trouble being closed, an authoritative answer would be appreciated in this matter, rather than opinion-based ones.
与链接的问题一样,因为它看起来很难被关闭,所以在这个问题上会得到权威的答案,而不是基于意见的答案。
1 个解决方案
#1
41
As we saw in What is the reason why “synchronized” is not allowed in Java 8 interface methods? and Why is "final" not allowed in Java 8 interface methods?, extending interfaces to define behavior is more subtle than it might first appear. It turns out that each of the possible modifiers has their own story; its not simply a matter of blindly copying from how classes work. (This is at least obvious in hindsight, as tools for OO modeling that work for single inheritance do not automatically work for multiple inheritance.)
正如我们所看到的那样,Java 8接口方法中不允许使用“synchronized”的原因是什么?为什么Java 8接口方法中不允许“最终”?,扩展接口以定义行为比首次出现时更加微妙。事实证明,每个可能的修饰语都有自己的故事;它不仅仅是盲目地复制类的工作方式。 (事后看来,这至少是显而易见的,因为用于单继承的OO建模工具不会自动用于多重继承。)
Let's start with the obvious answer: interfaces have always been restricted to only having public members, and while we added default methods and static methods to interfaces in Java 8, that doesn't mean we have to change everything just to be "more like" classes.
让我们从明显的答案开始:接口总是被限制为只有公共成员,而我们在Java 8中为接口添加了默认方法和静态方法,这并不意味着我们必须改变一切只是为了“更像”类。
Unlike with synchronized
and final
, which would have been serious mistakes to support for default methods, weaker accessibilities, especially private, are reasonable features to consider. Private interface methods, whether static or instance (note that these would not be defaults, since they do not participate in inheritance) are a perfectly sensible tool (though they can be easily simulated by nonpublic helper classes.)
与synchronized和final不同,这可能是支持默认方法的严重错误,较弱的可访问性,尤其是私有,是需要考虑的合理特性。私有接口方法,无论是静态还是实例(请注意,这些方法不是默认值,因为它们不参与继承)是一种非常明智的工具(尽管它们很容易被非公共帮助程序类模拟。)
We actually did consider doing private interface methods in Java 8; this was mostly something that just fell off the bottom of the list due to resource and time constraints. It is quite possible this feature might reappear on the to-do list some day.
我们确实考虑过在Java 8中使用私有接口方法;由于资源和时间限制,这大部分都是从列表底部掉下来的。很有可能这个功能有一天会重新出现在待办事项列表中。
Package and protected methods, however, are more complicated than they look; the complexity of multiple inheritance and the complexity of the true meaning of protected
would interact in all sorts of no-so-fun ways. So I wouldn't hold your breath for that.
然而,包和受保护的方法比它们看起来更复杂;多重继承的复杂性和受保护的真正含义的复杂性将以各种不那么有趣的方式相互作用。所以我不会屏住呼吸。
So, the short answer is, private interface methods is something we could have done in 8, but we couldn't do everything that could have been done and still ship, so it was cut, but could come back.
因此,简短的回答是,私有接口方法是我们本可以在8中完成的,但是我们无法完成所有可能已经完成并仍在发布的所有方法,因此它被削减了,但可能会回来。
#1
41
As we saw in What is the reason why “synchronized” is not allowed in Java 8 interface methods? and Why is "final" not allowed in Java 8 interface methods?, extending interfaces to define behavior is more subtle than it might first appear. It turns out that each of the possible modifiers has their own story; its not simply a matter of blindly copying from how classes work. (This is at least obvious in hindsight, as tools for OO modeling that work for single inheritance do not automatically work for multiple inheritance.)
正如我们所看到的那样,Java 8接口方法中不允许使用“synchronized”的原因是什么?为什么Java 8接口方法中不允许“最终”?,扩展接口以定义行为比首次出现时更加微妙。事实证明,每个可能的修饰语都有自己的故事;它不仅仅是盲目地复制类的工作方式。 (事后看来,这至少是显而易见的,因为用于单继承的OO建模工具不会自动用于多重继承。)
Let's start with the obvious answer: interfaces have always been restricted to only having public members, and while we added default methods and static methods to interfaces in Java 8, that doesn't mean we have to change everything just to be "more like" classes.
让我们从明显的答案开始:接口总是被限制为只有公共成员,而我们在Java 8中为接口添加了默认方法和静态方法,这并不意味着我们必须改变一切只是为了“更像”类。
Unlike with synchronized
and final
, which would have been serious mistakes to support for default methods, weaker accessibilities, especially private, are reasonable features to consider. Private interface methods, whether static or instance (note that these would not be defaults, since they do not participate in inheritance) are a perfectly sensible tool (though they can be easily simulated by nonpublic helper classes.)
与synchronized和final不同,这可能是支持默认方法的严重错误,较弱的可访问性,尤其是私有,是需要考虑的合理特性。私有接口方法,无论是静态还是实例(请注意,这些方法不是默认值,因为它们不参与继承)是一种非常明智的工具(尽管它们很容易被非公共帮助程序类模拟。)
We actually did consider doing private interface methods in Java 8; this was mostly something that just fell off the bottom of the list due to resource and time constraints. It is quite possible this feature might reappear on the to-do list some day.
我们确实考虑过在Java 8中使用私有接口方法;由于资源和时间限制,这大部分都是从列表底部掉下来的。很有可能这个功能有一天会重新出现在待办事项列表中。
Package and protected methods, however, are more complicated than they look; the complexity of multiple inheritance and the complexity of the true meaning of protected
would interact in all sorts of no-so-fun ways. So I wouldn't hold your breath for that.
然而,包和受保护的方法比它们看起来更复杂;多重继承的复杂性和受保护的真正含义的复杂性将以各种不那么有趣的方式相互作用。所以我不会屏住呼吸。
So, the short answer is, private interface methods is something we could have done in 8, but we couldn't do everything that could have been done and still ship, so it was cut, but could come back.
因此,简短的回答是,私有接口方法是我们本可以在8中完成的,但是我们无法完成所有可能已经完成并仍在发布的所有方法,因此它被削减了,但可能会回来。