Les méthodes d'une interface Java doivent-elles être déclarées avec ou sans modificateur d'accès public?

292

Les méthodes d'une interface Java doivent-elles être déclarées avec ou sans le publicmodificateur d'accès?

Techniquement, cela n'a pas d'importance, bien sûr. Une méthode de classe qui implémente un interfaceest toujours public. Mais qu'est-ce qu'une meilleure convention?

Java lui-même n'est pas cohérent à cet égard. Voir , par exemple par Collectionrapport à Comparable, ou Futurecontre ScriptEngine.

Benno Richters
la source
22
C'est mauvais parce que l'écrire en public implique qu'il peut être non public
Pacerier
8
Vous devez éviter la syntaxe redondante de toute forme.
Marquis de Lorne
3
@Pacerier, même si je reconnais que c'est mauvais à utiliser publicdans ce contexte, les méthodes d'interface par défaut peuvent désormais (avec java 9) être privées. Je vous suggère de supprimer votre commentaire car il est obsolète.
aioobe
2
Oui, les choses sont susceptibles de changer dans Java 9. "L'écrire en public implique qu'il peut être non public" . Etant donné que cela semble être possible en Java 9, cet argument a désormais l'avantage d'être écrit public.
MC Emperor

Réponses:

334

Le JLS le montre clairement:

Il est autorisé, mais déconseillé pour des raisons de style, de spécifier de manière redondante le modificateur publicet / ou abstractune méthode déclarée dans une interface.

Jon Skeet
la source
6
Le lien JLS ci-dessus était pour Java 7 au moment où je l'ai lu. Après les commentaires sur Java 9 autorisant les méthodes non publiques, je voulais juste confirmer que le libellé très similaire est toujours là pour SE9 JLS . (une publicpartie est la même, une and/or abstractpartie a été supprimée)
OzgurH
3
Toujours vrai dans SE11 JLS
Ortomala Lokni
44

Le modificateur public devrait être omis dans les interfaces Java (à mon avis).

Puisqu'il n'ajoute aucune information supplémentaire, il détourne juste l'attention des choses importantes.

La plupart des guides de style vous recommanderont de ne pas le mentionner, mais bien sûr, le plus important est d'être cohérent dans votre base de code, et en particulier pour chaque interface. L'exemple suivant pourrait facilement confondre quelqu'un qui ne maîtrise pas à 100% Java:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
Rasmus Faber
la source
3
Avez-vous un lien vers un tel guide de style?
Benno Richters
9
La cohérence est de loin la chose la plus importante et est la réponse à 99% de ces types de questions.
SCdF
Accord sur la cohérence. Quelque chose pour vos normes de codage documente les gars :)
JeeBee
2
Bno: Un exemple est la spécification du langage Java, un autre est Checkstyle.
Rasmus Faber
9

Malgré le fait que cette question a été posée il y a longtemps mais je pense qu'une description complète clarifierait pourquoi il n'est pas nécessaire d'utiliser un résumé public avant les méthodes et un final statique public avant les constantes d'une interface.

Tout d'abord, les interfaces sont utilisées pour spécifier des méthodes communes pour un ensemble de classes non liées pour lesquelles chaque classe aura une implémentation unique. Par conséquent, il n'est pas possible de spécifier le modificateur d'accès comme privé car il ne peut pas être accédé par d'autres classes à remplacer.

Deuxièmement, bien que l'on puisse initier des objets d'un type d'interface mais une interface est réalisée par les classes qui l'implémentent et non héritée. Et comme une interface peut être implémentée (réalisée) par différentes classes non liées qui ne sont pas dans le même package, le modificateur d'accès protégé n'est donc pas également valide. Donc, pour le modificateur d'accès, il ne nous reste que le choix public.

Troisièmement, une interface n'a aucune implémentation de données, y compris les variables et méthodes d'instance. S'il y a une raison logique d'insérer des méthodes ou des variables d'instance implémentées dans une interface, il doit s'agir d'une superclasse dans une hiérarchie d'héritage et non d'une interface. Compte tenu de ce fait, puisqu'aucune méthode ne peut être implémentée dans une interface, toutes les méthodes dans l'interface doivent donc être abstraites.

Quatrièmement, Interface ne peut inclure constant que ses membres de données, ce qui signifie qu'ils doivent être finaux et bien sûr les constantes finales sont déclarées statiques pour n'en conserver qu'une seule instance. Par conséquent, la finale statique est également un must pour les constantes d'interface.

Donc, en conclusion, bien que l'utilisation des méthodes abstract public avant et final statique avant public soit valide, mais comme il n'y a pas d'autres options, elle est considérée comme redondante et non utilisée.

Leo The Four
la source
7

Avec l'introduction de private, static, defaultmodificateurs pour les méthodes d'interface en Java 8/9, les choses deviennent plus compliquées et je tendance à penser que les déclarations complètes sont plus lisibles (Java 9 a besoin de compiler):

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
la source
5

J'éviterais de mettre des modificateurs appliqués par défaut. Comme indiqué, cela peut entraîner des incohérences et de la confusion.

Le pire que j'ai vu est une interface avec des méthodes déclarées abstract...

PhiLho
la source
5

J'ai utilisé des méthodes de déclaration avec le publicmodificateur, car cela rend le code plus lisible, en particulier avec la coloration syntaxique. Cependant, dans notre dernier projet, nous avons utilisé Checkstyle qui affiche un avertissement avec la configuration par défaut pourpublic modificateurs sur les méthodes d'interface, donc je suis passé à les ommettre.

Je ne suis donc pas vraiment sûr de ce qui est le mieux, mais une chose que je n'aime vraiment pas, c'est d'utiliser des public abstractméthodes d'interface. Eclipse le fait parfois lors de la refactorisation avec "Extraire l'interface".

cretzel
la source
2
Mais seulement si vous cochez les deux cases à cocher, déclarez les méthodes publiques, abstraites.
MetroidFan2002
4

J'écris toujours ce que j'utiliserais s'il n'y avait pas d'interface et j'écrivais une implémentation directe, c'est-à-dire que j'utiliserais public.

JeeBee
la source
6
Souhaitez-vous également déclarer explicitement toutes les méthodes d'interface abstraites?
Dan Dyer
4
C'est une interface, pas une classe abstraite. En ce qui concerne le «public», ce sont 7 caractères que vous avez tapés au moment où vous y pensez, gros problème! Et c'est ainsi qu'il sera défini dans l'implémentation, qui est +1 pour la cohérence, équilibrant le -1 pour la redondance.
JeeBee
3

Je préfère le sauter, j'ai lu quelque part que les interfaces sont par défaut, publicet abstract.

À ma grande surprise, le livre - Head First Design Patterns , utilisepublic avec la déclaration d'interface et les méthodes d'interface ... qui m'a fait repenser une fois de plus et j'ai atterri sur ce post.

Quoi qu'il en soit, je pense que les informations redondantes doivent être ignorées.

Pradeep Sharma
la source
1
Juste pour clarifier, si vous omettez le publicmodificateur d'accès sur la déclaration d'interface, il ne sera pas public et abstrait par défaut. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad
3

Je ne suis pas d'accord avec la réponse populaire, selon laquelle avoir du public implique qu'il existe d'autres options et que cela ne devrait donc pas exister. Le fait est que maintenant avec Java 9 et au-delà, il existe d'autres options.

Je pense que Java devrait plutôt imposer / exiger que «public» soit spécifié. Pourquoi? Parce que l'absence d'un modificateur signifie un accès «package» partout ailleurs, et avoir cela comme un cas spécial est ce qui conduit à la confusion. Si vous en faisiez simplement une erreur de compilation avec un message clair (par exemple "L'accès au package n'est pas autorisé dans une interface."), Nous nous débarrasserions de l'ambiguïté apparente qu'introduit l'option de laisser de côté "public".

Notez la formulation actuelle sur: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

"Une méthode dans le corps d'une interface peut être déclarée publique ou privée (§6.6). Si aucun modificateur d'accès n'est donné, la méthode est implicitement publique. Il est autorisé, mais découragé par style, de spécifier de manière redondante le public modificateur pour une déclaration de méthode dans une interface. "

Voyez que «privé» EST autorisé maintenant. Je pense que la dernière phrase aurait dû être supprimée du JLS. Il est regrettable que le comportement "implicitement public" ait jamais été autorisé car il restera probablement pour une compatibilité descendante et conduira à la confusion que l'absence du modificateur d'accès signifie "public" dans les interfaces et "package" ailleurs.

swpalmer
la source
2

La raison pour laquelle les méthodes dans les interfaces sont par défaut publiques et abstraites me semble tout à fait logique et évidente.

Une méthode dans une interface est par défaut abstraite pour forcer la classe d'implémentation à fournir une implémentation et est publique par défaut afin que la classe d'implémentation y ait accès.

L'ajout de ces modificateurs dans votre code est redondant et inutile et ne peut que conduire à la conclusion que vous manquez de connaissances et / ou de compréhension des principes fondamentaux de Java.

Iuliana Cosmina
la source
Mais vous pouvez également implémenter des méthodes abstraites qui ont un accès protégé - dans une classe abstraite. Le public n'est donc pas une exigence. Ajouter quelque chose d'explicite qui est le même que ce qui serait par défaut est toujours redondant, mais ce n'est pas toujours inutile.
swpalmer
Mais la question concerne les interfaces. Je ne voulais pas m'éloigner. Je veux dire, depuis Java 8, nous pouvons également parler de méthode privée et par défaut dans les interfaces, non? Cette discussion peut donc être assez longue si nous le voulons. ;)
Iuliana Cosmina
1

C'est totalement subjectif. J'omet le redondantpublic modificateur car il semble être encombré. Comme mentionné par d'autres, la cohérence est la clé de cette décision.

Il est intéressant de noter que les concepteurs du langage C # ont décidé d'imposer cela. Déclarer une méthode d'interface publique en C # est en fait une erreur de compilation. Cependant, la cohérence n'est probablement pas importante entre les langues, donc je suppose que ce n'est pas vraiment directement pertinent pour Java.

serg10
la source
-9

Les gens apprendront votre interface en complétant le code dans leur IDE ou en Javadoc, pas en lisant la source. Il est donc inutile de mettre "public" dans la source - personne ne lit la source.

Tim Boudreau
la source
8
Je dois vraiment être en désaccord avec l'affirmation selon laquelle personne ne lit la source. Je pense que beaucoup de gens utilisent par exemple F3 dans Eclipse pour zoomer sur le code. Des outils comme Maven offrent la possibilité de télécharger les sources, pas seulement le JavaDoc, pour une raison.
Benno Richters
Ce n'est pas la raison exacte pour ne pas ajouter de publicmodificateur d'accès à une interface. C'est par conception et après mûre réflexion.
mtk