Ahora que no todas las declaraciones de métodos en una interfaz Java son abstractas públicas, ¿deberían declararse los métodos con estos modificadores?

14

Comenzando con Java 8, los defaultmétodos se introdujeron en las interfaces. Efectivamente, esto significa que no todos los métodos en un interfaceson abstract.

Comenzando con Java 9 (tal vez), privatese permitirán métodos. Esto significa que no todos los métodos en un interfaceson public abstract.

La pregunta "¿Deberían declararse los métodos en una interfaz Java con o sin el publicmodificador de acceso?" se le preguntó en Stack Overflow en /programming/161633/should-methods-in-a-java-interface-be-declared-with-or-without-a-public-access-m

Allí, la mayoría de las respuestas argumentaron que public abstractno debería usarse porque ningún método en un interfacepuede ser otro que no sea public abstract. Ese ya no es el caso.

Entonces, a la luz de estas nuevas características de las interfaces, ¿deberían public abstractusarse las palabras clave en una declaración de método de interfaz Java?

En mi entorno específico, tendremos personas que son ingenieros de software con experiencia, pero que no tienen experiencia en Java, que leen código Java de vez en cuando. Siento que omitir las public abstractpalabras clave ahora creará un punto adicional de confusión para aquellos que no están familiarizados con el historial de cómo las interfaces llegaron a tener diferentes reglas para usar estas palabras clave.

David Campbell
fuente
55
¿comprobaste Java 8 JLS? La misma sección que en la respuesta anterior aceptada en SO sugiere que la introducción de métodos predeterminados no cambió la recomendación previa que se basó en las mismas consideraciones de redundancia: "Un método de interfaz que carece de un defaultmodificador o un staticmodificador es implícitamente abstract... Está permitido, pero desaconsejado como cuestión de estilo, especificar redundantemente el abstractmodificador para tal declaración de método ". ¿Por qué esperas que las cosas cambien?
mosquito
3
Pensé que las cosas podrían cambiar porque la condición para que un método esté implícitamente se abstractestá volviendo cada vez más complicada. En Java 9, esa misma oración podría ser: "Un método de interfaz que carece de un defaultmodificador o un staticmodificador o un privatemodificador es implícitamente abstracto ..." Además, los argumentos auxiliares para no usar explícitamente las palabras clave, a saber, que todos los métodos de interfaz son public abstract, ahora son discutibles.
David Campbell
TBH No entiendo el razonamiento detrás de los métodos "predeterminados", e incluso los métodos estáticos alcanzan fuera del alcance de lo que las interfaces están destinadas a hacer normalmente. No se supone que las interfaces estén cargadas de concreción. Es por eso que son tipos útiles para referencias.
Trixie Wolf
1
Los métodos predeterminados de @TrixieWolf permiten que las interfaces evolucionen. Anteriormente, y a diferencia de las clases, agregar un método interrumpiría cada implementación; ahora, puede hacer crecer una interfaz siempre que tenga un buen candidato predeterminado. Considere la adición de streamto java.util.Collection, o Map.getOrDefault(). ¡La alternativa es crear una nueva subinterfaz y hacer que todos se depriman, como Graphics2D, y nadie lo disfrutó!
SusanW

Respuestas:

2

Para ampliar la respuesta de StackOverflow:

  1. El publicmodificador de acceso no es necesario porque

    Cada declaración de método en el cuerpo de una interfaz es implícitamente pública (§6.6). Está permitido, pero desaconsejado como cuestión de estilo, especificar redundantemente el modificador público para una declaración de método en una interfaz. ( Sección 9.4 )

  2. El abstractmodificador de acceso no es necesario porque

    Un método predeterminado es un método que se declara en una interfaz con el modificador predeterminado; su cuerpo siempre está representado por un bloque .

    Y...

    Un método de interfaz que carece de un modificador predeterminado o un modificador estático es implícitamente abstracto , por lo que su cuerpo está representado por un punto y coma , no un bloque.

Dado que los métodos predeterminados tienen un cuerpo, y aquellos que no son inherentemente abstractos, y cada declaración de método en una interfaz es inherentemente pública, no necesita especificar ninguna palabra clave.


Uno de los comentarios sobre una respuesta decía:

¡No los hagas pensar! Siempre agregué un resumen público antes, a pesar del estilo policial, porque dejaba las cosas claras y recordaba al lector. Ahora estoy reivindicado porque Java 8 y 9 complican las cosas (user949300)

Un comentario sobre la pregunta de StackOverflow (votado 18 veces) refuta esto:

Es malo porque escribirlo como público implica que puede ser no público (Pacerier)

Las implicaciones del código, especialmente las interfaces, son importantes.

Greg Burghardt
fuente
El comentario que citó de StackOverflow ahora está desactualizado. Decir que agregar el modificador público es una mala escritura ya que implica que puede ser no público es contradictorio. El método puede ser no público.
David Campbell
@DavidCampbell: Bueno, creo que esta pregunta podría hacerse mejor después de que salga Java 9. :) La especificación de Java aún por finalizar podría responder a esta pregunta.
Greg Burghardt
1

¿No es suficiente la falta de una implicación de declaración de bloque? ¿Declararías, extends Objectaunque está implícito?

Si el desarrollador no comprende la redundancia, es probable que no comprenda completamente el concepto detrás de la función del lenguaje , que es un problema aún mayor que estar confundido acerca de los modificadores.

El desarrollador debe comprender que el propósito de una interfaz es crear un contrato que defina cómo un cliente puede interactuar con un objeto. Esto sugiere que cualquier método en una interfaz utilizada para la interacción de objetos debería exponerse a los clientes.

Si declara que un método es privado, está declarando explícitamente que los clientes no deben invocar ese método, lo que en el caso de las interfaces es algo que no se puede inferir fácilmente.

Vince Emigh
fuente
2
¡No los hagas pensar! Siempre agregué public abstractantes, a pesar del estilo policial, porque dejó las cosas claras y recordó al lector. Ahora estoy reivindicado porque Java 8 y 9 complican las cosas :-). Java ya es bastante redundante.
user949300
1
@ user949300 ¿También agregaría extends Objecta cada clase que se deriva directamente Object? Es información que un desarrollador ya debe conocer, por lo que se infiere. Mientras menos información inútil aparezca en la pantalla, más fácil será procesar la información importante. Espero haberte persuadido para que vengas al lado oscuro (¿lo entiendes? Porque las cosas implícitas no se pueden ver). Si no, valió la pena intentarlo jaja. Al final, todo se reduce a lo que hace que el código sea más fácil de administrar para el desarrollador
Vince Emigh, el
@ user949300 Al hacer esto, es más probable que cree confusión sobre lo que significa cuando los métodos de interfaz no contienen estas declaraciones. es decir, si hay desarrolladores que aprenden java al mirar su código, potencialmente ha obstaculizado su comprensión de la sintaxis de las declaraciones de interfaz.
JimmyJames
Vince, no, no extendería Object, aunque no hago ningún ataque cuando veo código que lo hace. @JimmyJames, si uno es consistente agregando un resumen público a los elementos que lo son, no veo ninguna confusión. ¿Me estoy perdiendo de algo? OTOH, veo tu punto sobre el desorden. Por ejemplo, no agrego finalargumentos de método anteriores a menos que algo divertido lo requiera (como una clase interna anónima, etc.)
user949300
@ user949300 Él quiere decir que si un usuario ya estuvo expuesto a la falta de modificadores y la razón detrás de esto, pueden cuestionar por qué los modificadores están allí cuando los ven, haciéndoles asumir que puede haber una razón real detrás de esto además de ser explícito . No lo vería mal si lo viera extends Object, pero definitivamente levantaría una bandera y me haría preguntar por qué. Como mencioné en la publicación, hacer tales cosas podría implicar que el desarrollador puede tener una mala comprensión de cómo funciona algo (puede no saber que todos los objetos ya se extienden Object, de ahí la extensión explícita)
Vince Emigh