Agora que nem todas as declarações de métodos em uma interface Java são abstratas públicas, os métodos devem ser declarados com esses modificadores?


14

A partir do Java 8, os defaultmétodos foram introduzidos nas interfaces. Efetivamente, isso significa que nem todos os métodos em um interfacesão abstract.

A partir do Java 9 (talvez), os privatemétodos serão permitidos. Isso significa que nem todos os métodos em um interfacesão public abstract.

A pergunta "Os métodos em uma interface Java devem ser declarados com ou sem o publicmodificador de acesso?" foi solicitado no Stack Overflow em /programming/161633/should-methods-in-a-java-interface-be-declared-with-or-without-a-public-access-m

Lá, a maioria das respostas argumentou que public abstractnão deveria ser usado porque nenhum método em um interfacepode ser outra coisa senão public abstract. Esse não é mais o caso.

Portanto, à luz desses novos recursos de interfaces, as public abstractpalavras - chave devem ser usadas em uma declaração de método de interface Java?

No meu ambiente específico, teremos pessoas que são engenheiros de software experientes, mas não experientes em Java, lendo o código Java de tempos em tempos. Sinto que deixar de fora as public abstractpalavras - chave criará um ponto de confusão adicional para aqueles que não estão familiarizados com o histórico de como as interfaces passaram a ter regras diferentes para o uso dessas palavras-chave.


5
você verificou o Java 8 JLS? A mesma seção da antiga resposta aceita no SO sugere que a introdução de métodos padrão não mudou a recomendação anterior, baseada nas mesmas considerações de redundância: "Um método de interface sem defaultmodificador ou staticmodificador é implicitamente abstract... É permitido, mas desencorajado por uma questão de estilo, a especificar redundantemente o abstractmodificador para uma declaração desse método ". Por que você espera que as coisas mudem?
mosquito

3
Eu pensei que as coisas pudessem mudar porque a condição para um método ser implicitamente abstractestá se tornando cada vez mais complicada. Em Java 9, a mesma frase poderia ser: "Um método de interface sem um defaultmodificador ou um staticmodificador ou um privatemodificador é implicitamente abstract ..." Além disso, os argumentos auxiliares para não usar explicitamente as palavras-chave, ou seja, que todos os métodos de interface são public abstract, agora são discutíveis.
David Campbell

TBH Não entendo o raciocínio por trás dos métodos "padrão", e até os métodos estáticos atingem o escopo de quais interfaces normalmente se destinam a fazer. As interfaces não devem ser sobrecarregadas com a concreção. É por isso que eles são tipos úteis para referências.
Trixie Wolf

1
Os métodos padrão do @TrixieWolf permitem que as interfaces evoluam. Anteriormente, e diferentemente das classes, a adição de um método quebraria todas as implementações; agora, você pode aumentar uma interface desde que tenha um bom candidato padrão. Considere a adição de streama java.util.Collectionou Map.getOrDefault(). Alternativa é criar uma nova sub-interface, e fazer com que todo mundo faça downcast, como o Graphics2D, e ninguém gostou disso!
SusanW

Respostas:


2

Para expandir a resposta do StackOverflow:

  1. O publicmodificador de acesso não é necessário porque

    Toda declaração de método no corpo de uma interface é implicitamente pública (§6.6). É permitido, mas desencorajado por uma questão de estilo, especificar de forma redundante o modificador público para uma declaração de método em uma interface. ( Seção 9.4 )

  2. O abstractmodificador de acesso não é necessário porque

    Um método padrão é um método declarado em uma interface com o modificador padrão; seu corpo é sempre representado por um bloco .

    E...

    Um método de interface sem um modificador padrão ou estático é implicitamente abstrato , portanto, seu corpo é representado por um ponto e vírgula , não um bloco.

Dado que os métodos padrão têm um corpo, e os que não são inerentemente abstratos, e toda declaração de método em uma interface é inerentemente pública, você não precisa especificar nenhuma das palavras-chave.


Um dos comentários em uma resposta dizia:

Não os faça pensar! Eu sempre adicionei resumo público antes, apesar do estilo polícia, porque isso tornava as coisas claras e lembrava o leitor. Agora estou justificado porque o Java 8 e 9 complicam as coisas (user949300)

Um comentário sobre a questão StackOverflow (votada 18 vezes mais) refuta isso:

É ruim porque escrevê-lo como público implica que pode não ser público (Pacerier)

As implicações do código, especialmente as interfaces, são importantes.


O comentário que você citou do StackOverflow agora está desatualizado. Dizer que adicionar o modificador público é uma escrita ruim, pois implica que ele pode ser não público é contraditório. O método pode ser não público.
David Campbell

@ DavidCampbell: Bem, acho que essa pergunta pode ser melhor formulada depois que o Java 9 for lançado. :) A especificação Java ainda não finalizada pode responder a esta pergunta.
Greg Burghardt

1

A falta de uma declaração de bloco não é suficiente? Você declararia, extends Objectembora implícito?

Se o desenvolvedor não entender a redundância, é provável que ele não entenda completamente o conceito por trás do recurso de linguagem , o que é um problema ainda maior do que ficar confuso com os modificadores.

O desenvolvedor deve entender que o objetivo de uma interface é criar um contrato que defina como um cliente pode interagir com um objeto. Isso sugere que qualquer método em uma interface usada para interação com objetos deve ser exposto aos clientes.

Se você declarar um método privado, estará explicitamente declarando que o método não deve ser chamado pelos clientes, o que no caso de interfaces é algo que não pode ser facilmente deduzido.


2
Não os faça pensar! Eu sempre adicionei public abstractantes, apesar do estilo policial, porque deixava as coisas claras e lembrava o leitor. Agora estou justificado porque o Java 8 e 9 complica as coisas :-). Java já é bastante redundante.
user949300

1
@ user949300 Você também adicionaria extends Objecta todas as classes que derivam diretamente Object? São informações de que um desenvolvedor já deve estar ciente, e é por isso que é inferido. Quanto menos informações inúteis na tela, mais fácil é processar as informações importantes. Espero ter convencido você a vir para o lado sombrio (entendeu? Porque coisas implícitas não podem ser vistas). Se não, valeu a pena um tiro haha. No final, tudo se resume ao que torna o código mais fácil de gerir para o desenvolvedor
Vince Emigh

@ user949300 Ao fazer isso, é mais provável que você crie confusão sobre o que significa quando os métodos de interface não contêm essas declarações. ou seja, se houver algum desenvolvedor aprendendo java olhando seu código, você potencialmente prejudicará a compreensão da sintaxe das declarações de interface.
21416 JimmyJames #

Vince, não, eu não estenderia o Object, apesar de não me encaixar quando vejo o código que o faz. @JimmyJames, se alguém for consistente adicionando resumo público aos itens que são assim, não vejo nenhuma confusão. Estou esquecendo de algo? OTOH, entendo seu ponto de vista sobre a desordem. Por exemplo, eu não adicionar finalantes de argumentos de método, a menos que algo engraçado exige isso (como uma classe interna anônima etc ...)
user949300

@ user949300 Ele quer dizer que se um usuário já foi exposto à falta de modificadores e a razão por trás disso, eles podem questionar por que os modificadores estão lá quando os veem, fazendo-os supor que pode haver uma razão real por trás dele, além de apenas ser explícita . Eu não daria uma surra se visse extends Object, mas definitivamente levantaria uma bandeira e me faria questionar o porquê. Como eu mencionei no post, fazer tais coisas poderia implicar que o desenvolvedor pode ter um mal-entendido de como funciona alguma coisa (pode não saber que todos os objetos já estendem Object, daí a extensão explícito)
Vince Emigh
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.