受保护的接口

为什么interface定义中的所有方法都是隐式public ? 为什么不允许一个protected方法?

因为界面应该是“你能从课堂以外看到什么”。 添加非公开的方法是没有意义的。

虽然经常被引用的原因是“接口定义了公共API”,但我认为这是过度简化。 (它也“循环”了)。

  • 嵌套接口可以是保护或私有的,如果是这种情况,它根本不定义公共接口。

  • 具有访问修饰符混合的接口是没有意义的; 例如部分公开,部分限制在与接口相同的包中的其他类。 事实上,在某些情况下,这可能是有用的,国际海事组织。

实际上,我认为使得一个接口的成员隐式公开化的部分原因它让Java更简单

  • 隐式的公共接口成员对于程序员来说更容易处理。 你有多less次看到代码(类)的方法访问修饰符的表面上是随机select的? 很多“普通”程序员很难理解如何最好地pipe理Java抽象边界1 。 将公共/保护/包添加到接口使其更难。

  • 隐式公共接口成员简化了语言规范…因此也是Java编译器编写者以及实现Reflection API的人员的任务。

这种思路使“界面定义公共API”成为语言devise的后果(或特征)……而不是相反。 实际上,这两条思路可能在Javadevise者的思想中并行发展。


1 – 当然,顶尖的程序员对这些东西没有任何困难,并且可能欢迎更丰富的访问控制function。 但是,当他们的代码交给其他人维护时会发生什么呢?

我不得不说,这个问题已经通过在Java 8中引入默认方法而被重新打开了。我现在正在处理的项目与接口的基本性质类似,意味着从实现中抽象出意图。

有几种情况下,我可以大大简化我的代码与“默认保护”的方法。 事实certificate,这实际上并不工作,因为接口仍然坚持Java 7逻辑。 由于上面提到的原因,正常的保护方法并没有什么特别的意义。 但是如果一个默认的公共方法需要一个不太可能改变的低级资源,并且可以通过一个受保护的方法来提供,那么在我看来,拥有“默认保护”的工作不仅会保持更清晰的代码,还会保护未来的用户意外虐待。

(这个悲剧并没有改变这样的事实,即我仍然需要将我的代码过分复杂化,但是我不打算在Oracle中提出一个function请求。)

因为接口定义了公共API。 任何受保护的内部细节都不属于界面。

您可以使用具有受保护抽象方法的抽象类,但接口仅限于公共方法和公共静态最终字段。

也许,因为它是一个接口 ,也就是在那里告诉客户他们可以用实例做什么,而不是告诉他们他们不能做什么。

一个接口意味着被用作外部世界的“契约”。 如果你想使用受保护的方法,你最好使用抽象类(当然,如果这是可用的Java)。 维基

另外,这篇文章也许有一些很好的答案: 为什么我不能有受保护的接口成员?

强烈地感觉到接口应该允许受保护的方法; 谁说接口必须在全世界所有人都能看到? 至于你的观点,它可能会混淆“普通”(阅读:无能)程序员:OOP的很多是关于正确地构造对象,类,包等,如果程序员很难做到一切正常,他有一个更大的问题。 Java是为这种types的东西而构build的。

由于实现类必须实现所有在你的接口中声明的方法,如果你的实现类在不同的包中,会发生什么?

接口如果你想使用类似于你所描述的东西进行抽象类或嵌套接口。

从代码样式中获取有关接口variables的信息,但仍适用于以下方法:

接口variables是隐含公开的,因为接口旨在提供一个应用程序编程接口(API),Java程序员可以完全访问它们以在其自己的应用程序中引用和实现。 由于一个接口可以用在与自己不同的Java包中,因此公共可视性确保程序代码可以访问这个variables。

唯一的情况是,当你想限制可视性到同一个包。 protected所有其他用途均不适用。 具体来说,通常使用protected方法来提供对后代的较低级别实现的一些细节的访问。 但是声明在接口中是没有意义的,因为没有更低级的实现要公开。

甚至包的情况也不是真正的接口。

为了实现你可能想要的,你需要两个接口,一个用于内部使用,另一个接口公开在公共API中。 (可能是内部的,但不一定是扩展公共的)或者像其他人指出的那样,是一个抽象的超类。

受保护的方法总是只有在子类扩展基类时才能由子类访问。

在接口的情况下,子类永远不会扩展接口。 它实现了接口。

受保护的方法可以通过扩展访问,而不是通过实现

声明内部子接口是一个很好的例子,但是在技术上你不能声明你的内部方法在Java接口中被protected

当然,您可以创build另一个用于扩展公共接口的内部接口:

 public interface YourPublicInterface { public void doThing1(); public void doThing2(); public void doThing3(); interface Internal extends YourPublicInterface { void doAnyInternalThing1(); void doAnyInternalThing2(); } } 

您可以使用包内的Internal接口,但是您应该接受YourPublicInterface任何子types(在公共方法中):

 public class AClassInYourPackage { public void someMethod(YourPublicInterface param) { if (param instanceof YourPublicInterface.Internal) { // run the optimized code } else { // run the general code } } } 

软件包外用户可以使用YourPublicInterface没有问题。

在一般的实践中,程序员在类似的情况下创build抽象类。 但是,在这种情况下,我们失去了多inheritance的好处。

接口成员总是在自身之外(在类或结构中)修改/实现,因此它们是隐式公开的,并且不允许访问修饰符。 即使是界面的成员也被公开实施。 但是,如果您希望在提供其实现的类中使其成员为私有的,那么您需要明确地实现该接口。

 interface IMyIF { int MyMeth(int x); } //then it is legal to implement IMyIF as shown here: class MyClass : IMyIF { int IMyIF.MyMeth(int x) { return x / 3; } } 

一个明确的实现为您提供了一种实现接口方法的方法,以便它不是提供实现的类的公共成员。