¿Deberían declararse los métodos en una interfaz Java con o sin un modificador de acceso público?

292

¿Deberían declararse los métodos en una interfaz Java con o sin el publicmodificador de acceso?

Técnicamente no importa, por supuesto. Un método de clase que implementa un interfacees siempre public. Pero, ¿qué es una convención mejor?

Java en sí no es consistente en esto. Véase, por ejemplo, Collectionfrente a Comparable, o Futurefrente ScriptEngine.

Benno Richters
fuente
22
Es malo porque escribirlo como público implica que puede ser no público
Pacerier
8
Debe evitar la sintaxis redundante de cualquier forma.
Marqués de Lorne
3
@Pacerier, aunque estoy de acuerdo en que es malo usarlo publicen este contexto, los métodos de interfaz predeterminados ahora pueden (con java 9) ser privados. Le sugiero que elimine su comentario ya que es obsoleto.
aioobe
2
Sí, las cosas están sujetas a cambios en Java 9. "Escribirlo como público implica que puede ser no público" . Como exactamente eso parece posible en Java 9, este argumento ahora tiene el beneficio de escribirlo public.
MC Emperor

Respuestas:

334

El JLS deja esto claro:

Está permitido, pero se desaconseja por cuestiones de estilo, especificar de forma redundante el modificador publicy / o abstractpara un método declarado en una interfaz.

Jon Skeet
fuente
66
El enlace JLS anterior era para Java 7 en el momento en que lo leí. Después de los comentarios sobre Java 9 que permite métodos no públicos, solo quería confirmar que todavía hay una redacción muy similar para SE9 JLS . ( publicparte es igual, and/or abstractparte se ha eliminado)
OzgurH
3
Sigue siendo cierto en SE11 JLS
Ortomala Lokni
44

El modificador público debe omitirse en las interfaces Java (en mi opinión).

Como no agrega ninguna información adicional, simplemente desvía la atención de las cosas importantes.

La mayoría de las guías de estilo recomendarán que lo omita, pero, por supuesto, lo más importante es ser coherente en su base de código, y especialmente para cada interfaz. El siguiente ejemplo podría confundir fácilmente a alguien que no es 100% fluido en Java:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
Rasmus Faber
fuente
3
¿Tienes un enlace a esa guía de estilo?
Benno Richters
99
La consistencia es, con mucho, lo más importante, y es la respuesta al 99% de este tipo de preguntas.
SCdF
Acordado re: consistencia. Algo para sus estándares de codificación documentos chicos :)
JeeBee 02 de
2
Bno: Un ejemplo es la Especificación del lenguaje Java, otro es Checkstyle.
Rasmus Faber
9

A pesar de que esta pregunta se hizo hace mucho tiempo, pero creo que una descripción completa aclararía por qué no hay necesidad de utilizar un resumen público antes de los métodos y un final público estático antes de las constantes de una interfaz.

En primer lugar, las interfaces se utilizan para especificar métodos comunes para un conjunto de clases no relacionadas para las cuales cada clase tendrá una implementación única. Por lo tanto, no es posible especificar el modificador de acceso como privado ya que otras clases no pueden acceder a él para ser anulado.

Segundo, aunque uno puede iniciar objetos de un tipo de interfaz, las clases que lo implementan realizan una interfaz y no la heredan. Y dado que una interfaz podría ser implementada (realizada) por diferentes clases no relacionadas que no están en el mismo paquete, el modificador de acceso protegido tampoco es válido. Entonces, para el modificador de acceso solo nos queda la elección pública.

En tercer lugar, una interfaz no tiene ninguna implementación de datos, incluidas las variables de instancia y los métodos. Si hay una razón lógica para insertar métodos implementados o variables de instancia en una interfaz, entonces debe ser una superclase en una jerarquía de herencia y no una interfaz. Considerando este hecho, dado que ningún método puede implementarse en una interfaz, por lo tanto, todos los métodos en la interfaz deben ser abstractos.

Cuarto, la interfaz solo puede incluir constantes como miembros de datos, lo que significa que deben ser finales y, por supuesto, las constantes finales se declaran como estáticas para mantener solo una instancia de ellas. Por lo tanto, static final también es imprescindible para las constantes de interfaz.

En conclusión, aunque el uso de los resúmenes públicos antes de los métodos y el público estático final antes de las constantes de una interfaz es válido, pero dado que no hay otras opciones, se considera redundante y no se usa.

Leo los cuatro
fuente
7

Con la introducción de private, static, defaultmodificadores de métodos de interfaz en Java 8/9, las cosas se complican más y tienden a pensar que las declaraciones completas son más legibles (9 necesita Java para compilar):

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() {}

}
Werner Thumann
fuente
5

Evitaría poner modificadores que se aplican por defecto. Como se señaló, puede generar inconsistencias y confusión.

Lo peor que vi es una interfaz con métodos declarados abstract...

PhiLho
fuente
5

Solía ​​declarar métodos con el publicmodificador, porque hace que el código sea más legible, especialmente con el resaltado de sintaxis. Sin embargo, en nuestro último proyecto, utilizamos Checkstyle que muestra una advertencia con la configuración predeterminada para los publicmodificadores en los métodos de interfaz, así que cambié a omitirlos.

Así que no estoy seguro de qué es lo mejor, pero una cosa que realmente no me gusta es usar public abstractmétodos de interfaz. Eclipse hace esto a veces cuando refactoriza con "Extract Interface".

Cretzel
fuente
2
Pero solo si marca las dos casillas de verificación, declarar los métodos como públicos, abstractos.
MetroidFan2002
4

Siempre escribo lo que usaría si no hubiera interfaz y estaba escribiendo una implementación directa, es decir, usaría public.

JeeBee
fuente
66
¿También declararías explícitamente todos los métodos de interfaz abstractos?
Dan Dyer el
44
Es una interfaz, no una clase abstracta. En cuanto a 'público', son 7 caracteres que has escrito cuando lo piensas, ¡gran cosa! Y también es cómo se definirá en la implementación, que es +1 para la coherencia equilibrando el -1 para la redundancia.
JeeBee
3

Prefiero omitirlo, leí en alguna parte que las interfaces son por defecto, publicy abstract.

Para mi sorpresa, el libro - Head First Design Patterns , está utilizando la publicdeclaración de interfaz y los métodos de interfaz ... eso me hizo repensar una vez más y llegué a esta publicación.

De todos modos, creo que la información redundante debería ser ignorada.

Pradeep Sharma
fuente
1
Solo para aclarar, si omite el publicmodificador de acceso en la declaración de la interfaz, no será público y abstracto de forma predeterminada. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad
3

No estoy de acuerdo con la respuesta popular, que tener público implica que hay otras opciones, por lo que no debería estar allí. El hecho es que ahora con Java 9 y más allá HAY otras opciones.

Creo que, en cambio, Java debería exigir / exigir que se especifique 'público'. ¿Por qué? Debido a que la ausencia de un modificador significa acceso a 'paquete' en cualquier otro lugar, y tener esto como un caso especial es lo que lleva a la confusión. Si simplemente cometió un error de compilación con un mensaje claro (por ejemplo, "No se permite el acceso al paquete en una interfaz"), nos libraríamos de la aparente ambigüedad que presenta la opción de omitir 'público'.

Tenga en cuenta la redacción actual en: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

"Un método en el cuerpo de una interfaz puede declararse público o privado (§6.6). Si no se proporciona un modificador de acceso, el método es implícitamente público. Se permite, pero se desaconseja por cuestiones de estilo, especificar de manera redundante el público modificador para una declaración de método en una interfaz ".

Ver que 'privado' está permitido ahora. Creo que la última oración debería haberse eliminado del JLS. Es lamentable que alguna vez se haya permitido el comportamiento "implícitamente público", ya que ahora probablemente seguirá siendo compatible con versiones anteriores y generará la confusión de que la ausencia del modificador de acceso significa 'público' en las interfaces y 'paquete' en otros lugares.

swpalmer
fuente
2

La razón por la cual los métodos en las interfaces son por defecto públicos y abstractos me parece bastante lógica y obvia.

Un método en una interfaz es, por defecto, abstracto para forzar a la clase implementadora a proporcionar una implementación y es público de manera predeterminada para que la clase implementadora tenga acceso para hacerlo.

Agregar esos modificadores en su código es redundante e inútil y solo puede llevar a la conclusión de que carece de conocimiento y / o comprensión de los fundamentos de Java.

Iuliana Cosmina
fuente
Pero también puede implementar métodos abstractos que tengan acceso protegido, en una clase abstracta. Entonces público no es un requisito. Agregar algo explícito que sea lo mismo que lo predeterminado sería siempre redundante, pero no siempre es inútil.
swpalmer
Pero la pregunta es sobre las interfaces. No quería desviarme. Quiero decir, desde Java 8, también podemos hablar sobre el método privado y predeterminado en las interfaces, ¿verdad? Entonces esta discusión puede hacerse bastante larga si queremos. ;)
Iuliana Cosmina
1

Es totalmente subjetivo. Omito el publicmodificador redundante ya que parece desorden. Como lo mencionaron otros, la consistencia es la clave de esta decisión.

Es interesante notar que los diseñadores del lenguaje C # decidieron hacer cumplir esto. Declarar un método de interfaz como público en C # es en realidad un error de compilación. Sin embargo, la consistencia probablemente no sea importante en todos los idiomas, por lo que supongo que esto no es realmente relevante para Java.

serg10
fuente
-9

La gente aprenderá su interfaz al completar el código en su IDE o en Javadoc, no al leer la fuente. Así que no tiene sentido poner "público" en la fuente: nadie está leyendo la fuente.

Tim Boudreau
fuente
8
Realmente tengo que estar en desacuerdo con la afirmación de que nadie está leyendo la fuente. Creo que mucha gente usa, por ejemplo, F3 en Eclipse para ampliar el código. Herramientas como Maven ofrecen la opción de descargar las fuentes, no solo JavaDoc, por una razón.
Benno Richters
Esa no es la razón exacta para no agregar un publicmodificador de acceso a una interfaz. Es por diseño y después de pensarlo detenidamente.
mtk