是否应使用或不使用公共访问修饰符声明Java接口中的方法?

时间:2008-10-02 10:13:22

标签: java interface coding-style public-method

是否应使用或不使用public访问修饰符声明Java接口中的方法?

技术上,当然没关系。实现interface的类方法始终为public。但什么是更好的惯例?

Java本身并不一致。例如,请参阅CollectionComparableFutureScriptEngine的对比。

12 个答案:

答案 0 :(得分:321)

JLS说明了这一点:

  

允许但不鼓励作为样式,为接口中声明的方法冗余指定public和/或abstract修饰符。

答案 1 :(得分:41)

Java接口中应省略public修饰符(在我看来)。

由于它没有添加任何额外的信息,它只会引起人们对重要事物的注意。

大多数样式指南都会建议您将其删除,但当然,最重要的是在整个代码库中保持一致,特别是对于每个界面。以下示例可能会让一些不熟悉Java的人感到困惑:

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

答案 2 :(得分:8)

尽管很久以前就已经问过这个问题,但我觉得全面的描述会澄清为什么在接口常量之前不需要在方法和公共静态最终之前使用公共摘要。

首先,接口用于为一组不相关的类指定通用方法,每个类都有一个独特的实现。因此,无法将访问修饰符指定为私有,因为要覆盖的其他类无法访问它。

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

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

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

所以总的来说,尽管在接口的常量之前使用方法之前的公共抽象和公共静态final是有效的但是因为没有其他选项,所以它被认为是冗余的而不是使用的。

答案 3 :(得分:6)

随着Java 8/9中接口方法的privatestaticdefault修饰符的引入,事情变得更加复杂,我倾向于认为完整的声明更具可读性(需要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() {}

}

答案 4 :(得分:5)

我会避免使用默认应用的修饰符。正如所指出的,它可能导致不一致和混乱。

我看到的最糟糕的是一个声明为abstract ...

的方法的接口

答案 5 :(得分:5)

我使用了public修饰符的declare方法,因为它使代码更具可读性,特别是在语法高亮的情况下。在我们的最新项目中,我们使用了Checkstyle,它在接口方法上显示了public修饰符的默认配置警告,因此我切换到省略它们。

所以我不确定什么是最好的,但有一点我真的不喜欢在接口方法上使用public abstract。 Eclipse在使用“Extract Interface”重构时有时会这样做。

答案 6 :(得分:4)

如果没有界面,我总是写下我会使用的内容,而我正在编写直接实现,即我会使用public

答案 7 :(得分:3)

我更喜欢跳过它,我在某处读到默认接口,publicabstract

令我惊讶的是,这本书 - Head First Design Patterns正在使用public使用界面声明和界面方法...这让我再次重新思考,我登上了这篇文章。

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

答案 8 :(得分:2)

接口中的方法默认为public和abstract的原因对我来说似乎很合乎逻辑。

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

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

答案 9 :(得分:2)

我不同意这个普遍的答案,公众拥有意味着还有其他选择,因此不应存在。事实是,现在使用Java 9或更高版本,还有其他选择。

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

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

  

“接口主体中的方法可以声明为 public 或   私有(第6.6节)。如果没有给出访问修饰符,则该方法是隐式公共的。这是允许的,但是由于   样式,以冗余方式指定方法的public修饰符   接口中的声明。”

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

答案 10 :(得分:1)

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

值得注意的是,C#语言设计师决定强制执行此操作。 在C#中将接口方法声明为public是一个编译错误。但是,对于语言而言,一致性可能并不重要,所以我想这与Java没有直接关系。

答案 11 :(得分:-9)

人们将从IDE或Javadoc中的代码完成中学习您的界面,而不是从阅读源。所以把“公共”放在源头是没有意义的 - 没有人在阅读消息来源。