Os métodos em uma interface Java devem ser declarados com ou sem um modificador de acesso público?

292

Os métodos em uma interface Java devem ser declarados com ou sem o publicmodificador de acesso?

Tecnicamente, isso não importa, é claro. Um método de classe que implementa um interfaceé sempre public. Mas o que é uma convenção melhor?

O próprio Java não é consistente nisso. Ver, por exemplo Collectionvs. Comparableou Futurevs. ScriptEngine.

Benno Richters
fonte
22
É ruim porque escrevê-lo como público implica que pode ser não-pública
Pacerier
8
Você deve evitar a sintaxe redundante de qualquer forma.
Marquês de Lorne
3
@ Pacerier, embora eu concorde que é ruim usar publicneste contexto, os métodos de interface padrão agora podem (com o java 9) ser privados. Sugiro que você remova seu comentário, pois é obsoleto.
Aioobe2
2
Sim, as coisas estão sujeitas a alterações no Java 9. "Escrever como público implica que pode não ser público" . Como exatamente isso parece ser possível no Java 9, esse argumento está agora no benefício de realmente ser redigido public.
MC Emperor

Respostas:

334

O JLS deixa isso claro:

É permitido, mas desencorajado por uma questão de estilo, especificar redundantemente o publice / ou abstractmodificador para um método declarado em uma interface.

Jon Skeet
fonte
6
O link JLS acima era para Java 7 no momento em que o li. Após os comentários sobre o Java 9, que permitem métodos não públicos, eu só queria confirmar que ainda existem expressões muito semelhantes para o SE9 JLS . ( publicParte é mesmo, and/or abstractparte foi descartado)
OzgurH
3
Ainda é verdade no SE11 JLS
Ortomala Lokni
44

O modificador público deve ser omitido nas interfaces Java (na minha opinião).

Como não adiciona nenhuma informação extra, apenas desvia a atenção das coisas importantes.

A maioria dos guias de estilo recomendará que você o deixe de fora, mas é claro que o mais importante é ser consistente em toda a sua base de código, e especialmente em cada interface. O exemplo a seguir pode facilmente confundir alguém que não é 100% fluente em Java:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
Rasmus Faber
fonte
3
Você tem um link para esse guia de estilo?
Benno Richters
9
A consistência é de longe a coisa mais importante e é a resposta para 99% desses tipos de perguntas.
SCdF 02/10/08
Re: consistência acordada. Algo para documentos seus padrões de codificação caras :)
JeeBee
2
Nota: Um exemplo é a Especificação da Linguagem Java, outro é o Checkstyle.
Rasmus Faber
9

Apesar do fato de essa pergunta ter sido feita há muito tempo, mas sinto que uma descrição abrangente esclareceria por que não há necessidade de usar resumo público antes dos métodos e final estático público antes das constantes de uma interface.

Antes de tudo, as interfaces são usadas para especificar métodos comuns para um conjunto de classes não relacionadas, para as quais cada classe terá uma implementação exclusiva. Portanto, não é possível especificar o modificador de acesso como privado, pois ele não pode ser acessado por outras classes a serem substituídas.

Segundo, embora se possa iniciar objetos de um tipo de interface, uma interface é realizada pelas classes que o implementam e não são herdadas. E como uma interface pode ser implementada (realizada) por diferentes classes não relacionadas que não estão no mesmo pacote, o modificador de acesso protegido também não é válido. Portanto, para o modificador de acesso, resta apenas a escolha pública.

Terceiro, uma interface não possui nenhuma implementação de dados, incluindo as variáveis ​​e métodos da instância. Se houver motivo lógico para inserir métodos implementados ou variáveis ​​de instância em uma interface, ele deverá ser uma superclasse em uma hierarquia de herança e não uma interface. Considerando esse fato, como nenhum método pode ser implementado em uma interface, portanto, todos os métodos na interface devem ser abstratos.

Quarto, a Interface só pode incluir constante como seus membros de dados, o que significa que eles devem ser finais e, é claro, as constantes finais são declaradas como estáticas para manter apenas uma instância delas. Portanto, final estático também é uma obrigação para constantes da interface.

Portanto, em conclusão, embora o uso de abstract público antes de métodos e público estático final antes de constantes de uma interface seja válido, mas como não há outras opções, ele é considerado redundante e não usado.

Leo os quatro
fonte
7

Com a introdução de private, static, defaultmodificadores para métodos de interface em Java 8/9, as coisas ficam mais complicadas e eu tendem a pensar que as declarações completas são mais legível (precisa de Java 9 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
fonte
5

Eu evitaria colocar modificadores aplicados por padrão. Como apontado, pode levar a inconsistência e confusão.

O pior que vi é uma interface com métodos declarados abstract...

PhiLho
fonte
5

Eu usei métodos de declaração com o publicmodificador, porque torna o código mais legível, especialmente com destaque de sintaxe. No entanto, em nosso projeto mais recente, usamos o Checkstyle, que mostra um aviso com a configuração padrão para publicmodificadores nos métodos de interface, então mudei para omiti-los.

Portanto, não tenho certeza do que é melhor, mas uma coisa que realmente não gosto é de usar public abstractmétodos de interface. O Eclipse faz isso algumas vezes ao refatorar com "Extract Interface".

Cretzel
fonte
2
Mas somente se você marcar as duas caixas de seleção, declarar métodos como públicos, abstratos.
MetroidFan2002
4

Eu sempre escrevo o que usaria se não houvesse interface e escrevia uma implementação direta, ou seja, usaria public.

JeeBee
fonte
6
Você também declararia explicitamente todos os métodos de interface abstratos?
Dan 'Dyer
4
É uma interface, não uma classe abstrata. No que diz respeito a 'público', são 7 caracteres que você digitou quando pensa nisso, grande coisa! E é também como será definido na implementação, que é +1 para consistência equilibrando o -1 para redundância.
JeeBee
3

Eu prefiro pular, eu li em algum lugar que as interfaces são por padrão, publice abstract.

Para minha surpresa, o livro - Head First Design Patterns , está usando publiccom declaração de interface e métodos de interface ... que me fez repensar mais uma vez e eu parei neste post.

De qualquer forma, acho que informações redundantes devem ser ignoradas.

Pradeep Sharma
fonte
1
Apenas para esclarecer, se você omitir o publicmodificador de acesso na declaração da interface, ele não será público e abstrato por padrão. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad
3

Eu discordo da resposta popular, que ter público implica que existem outras opções e, portanto, não deveria estar lá. O fato é que agora com o Java 9 e além existem outras opções.

Em vez disso, acho que o Java deve impor / exigir que 'public' seja especificado. Por quê? Como a ausência de um modificador significa acesso ao 'pacote' em qualquer outro lugar, e ter isso como um caso especial é o que leva à confusão. Se você simplesmente cometesse um erro de compilação com uma mensagem clara (por exemplo, "O acesso ao pacote não é permitido em uma interface"), nos livraríamos da aparente ambiguidade que é apresentada a opção de deixar de fora o 'público'.

Observe a redação atual em: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

"Um método no corpo de uma interface pode ser declarado público ou privado (§6.6). Se nenhum modificador de acesso for fornecido, o método é implicitamente público. É permitido, mas desencorajado por uma questão de estilo, especificar de forma redundante o público modificador para uma declaração de método em uma interface ".

Veja que 'privado' é permitido agora. Penso que a última frase deveria ter sido removida do JLS. É lamentável que o comportamento "implicitamente público" tenha sido permitido, uma vez que agora provavelmente permanecerá para compatibilidade com versões anteriores e levará à confusão de que a ausência do modificador de acesso significa 'público' em interfaces e 'pacote' em outros lugares.

swpalmer
fonte
2

A razão pela qual os métodos nas interfaces são, por padrão, públicos e abstratos, parece bastante lógica e óbvia para mim.

Um método em uma interface é por padrão abstrato forçar a classe de implementação a fornecer uma implementação e é público por padrão, para que a classe de implementação tenha acesso a isso.

A adição desses modificadores ao seu código é redundante e inútil e só pode levar à conclusão de que você não tem conhecimento e / ou entendimento dos fundamentos de Java.

Iuliana Cosmina
fonte
Mas você também pode implementar métodos abstratos que protegeram o acesso - em uma classe abstrata. Portanto, público não é um requisito. A adição de algo explícito igual ao que seria o padrão é sempre redundante, mas nem sempre é inútil.
swpalmer
Mas a questão é sobre interfaces. Eu não queria discordar. Quero dizer, desde o Java 8, também podemos falar sobre o método privado e padrão nas interfaces, certo? Portanto, essa discussão pode ser longa, se quisermos. ;)
Iuliana Cosmina
1

É totalmente subjetivo. Eu omito o publicmodificador redundante porque parece desorganização. Como mencionado por outros - a consistência é a chave para esta decisão.

É interessante notar que os designers de linguagem C # decidiram aplicar isso. Declarar um método de interface como público em C # é realmente um erro de compilação. A consistência provavelmente não é importante entre as linguagens, então acho que isso não é diretamente relevante para o Java.

serg10
fonte
-9

As pessoas aprenderão sua interface com a conclusão do código no IDE ou no Javadoc, e não com a leitura da fonte. Portanto, não faz sentido colocar "público" na fonte - ninguém está lendo a fonte.

Tim Boudreau
fonte
8
Eu realmente tenho que discordar da afirmação de que ninguém está lendo a fonte. Eu acho que muitas pessoas usam, por exemplo, F3 no Eclipse para ampliar o código. Ferramentas como o Maven oferecem a opção de baixar as fontes, não apenas o JavaDoc, por um motivo.
precisa saber é o seguinte
Esse não é o motivo exato para não adicionar um publicmodificador de acesso a uma interface. É por design e após um cuidadoso pensamento por trás disso.
mtk