是否应该在Java接口中的方法声明为带有或不带有公共访问修饰符?


292

是否应该在Java接口中的方法声明带有或不带有publicaccess修饰符?

当然,从技术上讲,这并不重要。实现an的类方法interface始终为public。但是什么是更好的约定?

Java本身与此不一致。例如参见Collectionvs. ComparableFuturevs ScriptEngine.。


22
这是不好的,因为写它作为公共意味着它可以是非公
Pacerier

8
您应避免使用任何形式的冗余语法。
2013年

3
@Pacerier,虽然我同意public在这种情况下使用是不好的,但是默认接口方法现在可以(对于Java 9)是私有的。我建议您删除您的评论,因为它已过时。
aioobe '16

2
是的,Java 9中的内容可能会发生变化。“将其写为公开意味着它可以是非公开的”。由于在Java 9 似乎完全可以实现,因此该参数现在受益于确实写出public
MC Emperor

Answers:


334

JLS了这一点:

允许(但不鼓励使用样式)为接口中声明的方法重复指定publicand /或abstract修饰符。


6
上面的JLS链接在我阅读时是针对Java 7的。关于Java 9允许使用非公共方法的评论之后,我只是想确认SE9 JLS的措辞仍然非常相似。(public部分相同,and/or abstract部分已删除)
OzgurH



44

我认为Java接口中应该省略public修饰符。

由于它不会添加任何额外的信息,因此只会引起人们对重要内容的注意。

大多数样式指南都建议您不要使用它,但是,当然,最重要的是在整个代码库中保持一致,尤其是对于每个接口而言。下面的示例很容易使不熟练使用Java的人感到困惑:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}

3
您是否有指向此类样式指南的链接?
Benno Richters

9
到目前为止,一致性是最重要的,它是对此类问题中99%的答案。
SCdF

同意re:一致性。一些适合您的编码标准文档的人:)
JeeBee

2
Bno:一个示例是Java语言规范,另一个是Checkstyle。
Rasmus Faber

9

尽管事实上这个问题已经问了很久了,但是我认为对它的全面描述可以澄清为什么在方法的接口常量之前不需要使用公共抽象,而在方法的常量之前不需要使用public static final。

首先,接口用于为一组不相关的类指定通用方法,每个类都将具有唯一的实现。因此,不可能将access修饰符指定为private,因为其他类无法覆盖它。

其次,尽管可以启动接口类型的对象,但是接口是由实现该接口的类实现的,而不是继承的。并且由于接口可能是由不在同一个程序包中的不同无关类实现(实现)的,因此受保护的访问修饰符也无效。因此,对于访问修饰符,我们只有公共选择权。

第三,接口没有任何数据实现,包括实例变量和方法。如果出于逻辑原因在接口中插入已实现的方法或实例变量,则它必须是继承层次结构中的超类,而不是接口。考虑到这一事实,由于接口中无法实现任何方法,因此接口中的所有方法都必须是抽象的。

第四,接口只能包含常量作为其数据成员,这意味着它们必须是最终的,当然最终常量被声明为静态的,以仅保留它们的一个实例。因此,对于接口常量,static final也是必须的。

因此,总之,尽管在接口常量之前使用公共抽象方法和在方法常量之前使用公共静态最终方法是有效的,但是由于没有其他选择,因此它被认为是多余的,因此不使用。


7

随着引进的privatestaticdefault在Java 8/9接口方法改性剂,事情变得更加复杂,我倾向于认为完全声明是更具可读性(需要Java 9编译):

public interface MyInterface {

    //minimal
    int CONST00 = 0;
    void method00();
    static void method01() {}
    default void method02() {}
    private static void method03() {}
    private void method04() {}

    //full
    public static final int CONST10 = 0;
    public abstract void method10();
    public static void method11() {}
    public default void method12() {}
    private static void method13() {}
    private void method14() {}

}

5

我会避免放置默认情况下应用的修饰符。如前所述,它可能导致不一致和混乱。

我看到的最糟糕的是带有声明的方法的接口abstract...


5

我使用带public修饰符的声明方法,因为它使代码更具可读性,尤其是在语法突出显示时。不过,在我们最新的项目中,我们使用了Checkstyle,它使用public接口方法的修饰符的默认配置显示警告,因此我改用省略它们。

所以我不确定什么是最好的,但是我不喜欢的一件事是public abstract在接口方法上使用。Eclipse在使用“提取接口”进行重构时有时会这样做。


2
但仅当您选中两个复选框时,才将方法声明为公共抽象方法。
MetroidFan2002

4

如果没有接口,而我正在写一个直接的实现,那我总是写我会用的东西,即我会使用public


6
您还会明确声明所有接口方法抽象吗?
Dan Dyer

4
它是一个接口,而不是抽象类。至于“公开”,到您考虑时已经键入了7个字符,这很重要!这也是在实现中的定义方式,它是+1表示一致性,而-1表示冗余。
JeeBee

3

我更喜欢跳过它,在某处阅读到默认情况下是接口,public并且abstract

令我惊讶的是,《Head First Design Patterns》一书正public与接口声明和接口方法一起使用……使我再次重新思考,我找到了这篇文章。

无论如何,我认为多余的信息应该被忽略。


1
只是为了澄清一下,如果public在接口声明上省略了访问修饰符,则默认情况下它将不是公共的和抽象的。docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad 2014年

3

我不同意普遍的回答,即公开表示存在其他选择,因此不应存在。事实是,现在使用Java 9或更高版本,还有其他选择。

我认为Java应该强制执行/要求指定“ public”。为什么?因为缺少修饰符意味着在其他任何地方都可以“打包”访问,并且将其作为特例会导致混淆。如果只用一条清晰的消息使它成为编译错误(例如“接口中不允许程序包访问。”),我们将摆脱明显的含糊不清之处,即可以忽略“公共”选项。

请注意以下当前措辞:https//docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

“接口主体中的方法可以声明为公共私有(第6.6节)。如果未提供访问修饰符,则该方法为隐式公共。允许(但出于风格考虑,不鼓励使用)冗余地指定公共接口中方法声明的修饰符。”

看到现在允许“私有”。我认为最后一句话应该从联合检查组中删除。不幸的是,曾经允许“隐式公开”行为,因为它现在可能仍会向后兼容,并导致混淆,即缺少访问修饰符意味着接口中的“公开”和其他位置的“打包”。


2

默认情况下,接口中的方法为public和abstract的原因对我来说似乎很合逻辑且显而易见。

接口中的方法默认情况下是抽象的,以强制实现类提供实现,并且默认情况下是公共的,因此实现类可以访问此方法。

在代码中添加这些修饰符是多余且无用的,只会导致您缺乏对Java基础知识和/或了解的结论。


但是,您也可以在抽象类中实现具有受保护访问权限的抽象方法。因此公开不是必需的。添加与默认值相同的显式内容总是多余的,但并非总是无用的。
swpalmer

但是问题是关于接口的。我不想离题。我的意思是,从Java 8开始,我们还可以讨论接口中的私有方法和默认方法,对吗?因此,如果我们愿意的话,可以进行很长的讨论。;)
Iuliana Cosmina

1

这完全是主观的。我忽略了多余的public修饰符,因为它看起来很混乱。正如其他人所提到的,一致性是此决定的关键。

有趣的是,C#语言设计师决定强制执行此操作。 在C#中将接口方法声明为公共方法实际上是编译错误。 但是,跨语言的一致性可能并不重要,因此我想这与Java并没有直接的关系。


-9

人们将通过其IDE或Javadoc中的代码完成来学习您的界面,而不是通过阅读源代码来学习。因此,在源代码中添加“公共”是没有意义的-没有人阅读源代码。


8
我真的不同意没有人在阅读源代码的说法。我认为很多人使用Eclipse中的F3例如来放大代码。出于某种原因,Maven之类的工具提供了下载源代码的选项,而不仅仅是JavaDoc。
Benno Richters 2012年

这不是不向public接口添加访问修饰符的确切原因。这是设计使然,经过仔细的思考。
mtk 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.