Java接口中的方法应该使用或不使用公共访问修饰符来声明?
当然,从技术上讲,这并不重要。实现接口的类方法总是公共的。但是什么是更好的约定呢?
Java本身在这方面并不一致。参见Collection vs. Comparable或Future vs. ScriptEngine。
Java接口中的方法应该使用或不使用公共访问修饰符来声明?
当然,从技术上讲,这并不重要。实现接口的类方法总是公共的。但是什么是更好的约定呢?
Java本身在这方面并不一致。参见Collection vs. Comparable或Future vs. ScriptEngine。
当前回答
尽管这个问题很久以前就被问过了,但我觉得一个全面的描述可以解释为什么没有必要在方法之前使用公共抽象,在接口的常量之前使用公共静态final。
首先,接口用于为一组不相关的类指定通用方法,其中每个类都有唯一的实现。因此,不可能将访问修饰符指定为private,因为它不能被其他要重写的类访问。
第二,虽然可以初始化接口类型的对象,但接口是由实现它的类实现的,而不是继承的。由于接口可能由不在同一个包中的不同不相关的类实现(实现),因此受保护访问修饰符也无效。因此,对于访问修饰符,我们只剩下公共选择。
第三,接口没有任何数据实现,包括实例变量和方法。如果在逻辑上有理由在接口中插入实现的方法或实例变量,那么它必须是继承层次结构中的超类,而不是接口。考虑到这一点,由于没有方法可以在接口中实现,因此接口中的所有方法都必须是抽象的。
第四,Interface只能包含常量作为它的数据成员,这意味着它们必须是final常量,当然final常量被声明为静态以只保留它们的一个实例。因此,静态final也是接口常量的必须值。
因此,总的来说,虽然在接口的方法之前使用公共抽象,在接口的常量之前使用公共静态final是有效的,但由于没有其他选项,因此被认为是多余的,不使用。
其他回答
我总是写我在没有接口的情况下使用的东西,我在写一个直接的实现,也就是说,我将使用public。
我使用带有公共修饰符的声明方法,因为它使代码更具可读性,特别是语法高亮显示。不过,在我们最新的项目中,我们使用了Checkstyle,它在接口方法上的公共修饰符的默认配置中显示了一个警告,所以我切换到忽略它们。
我不确定什么是最好的,但我不喜欢在接口方法上使用公共抽象。Eclipse在使用“Extract Interface”重构时有时会这样做。
我不同意流行的回答,公开意味着有其他选择,所以不应该存在。事实上,现在有了Java 9及以后的版本,就有了其他的选择。
我认为Java应该强制/要求指定“public”。为什么?因为没有修饰符意味着“包”访问其他任何地方,而将其作为特殊情况会导致混淆。如果你只是简单地将其设置为一个带有明确消息的编译错误(例如。“在接口中不允许访问包。”)我们将摆脱选择去掉“public”所带来的明显的模糊性。
请注意当前的措辞:https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4
接口体中的方法可以声明为public或 私人(§6.6)。如果没有给出访问修饰符,则该方法是隐式公共的。这是允许的,但不鼓励 样式,以冗余地指定方法的公共修饰符 在接口中声明。”
看,“私人”现在是允许的。我认为最后一句话应该从JLS中删除。不幸的是,“隐式公共”行为曾经被允许,因为它现在可能会为了向后兼容而保留,并导致混淆,即访问修饰符的缺失在接口中意味着“公共”,而在其他地方意味着“包”。
随着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() {}
}
尽管这个问题很久以前就被问过了,但我觉得一个全面的描述可以解释为什么没有必要在方法之前使用公共抽象,在接口的常量之前使用公共静态final。
首先,接口用于为一组不相关的类指定通用方法,其中每个类都有唯一的实现。因此,不可能将访问修饰符指定为private,因为它不能被其他要重写的类访问。
第二,虽然可以初始化接口类型的对象,但接口是由实现它的类实现的,而不是继承的。由于接口可能由不在同一个包中的不同不相关的类实现(实现),因此受保护访问修饰符也无效。因此,对于访问修饰符,我们只剩下公共选择。
第三,接口没有任何数据实现,包括实例变量和方法。如果在逻辑上有理由在接口中插入实现的方法或实例变量,那么它必须是继承层次结构中的超类,而不是接口。考虑到这一点,由于没有方法可以在接口中实现,因此接口中的所有方法都必须是抽象的。
第四,Interface只能包含常量作为它的数据成员,这意味着它们必须是final常量,当然final常量被声明为静态以只保留它们的一个实例。因此,静态final也是接口常量的必须值。
因此,总的来说,虽然在接口的方法之前使用公共抽象,在接口的常量之前使用公共静态final是有效的,但由于没有其他选项,因此被认为是多余的,不使用。