web-dev-qa-db-fra.com

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

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

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

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

265
Benno Richters

Le JLS est clair:

Il est permis, mais déconseillé en termes de style, de spécifier de manière redondante le modificateur public et/ou abstract pour une méthode déclarée dans une interface.

316
Jon Skeet

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

Comme cela n’ajoute aucune information supplémentaire, cela détourne simplement l’attention des choses importantes.

La plupart des guides de style vous recommanderont de le laisser de côté, 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 dérouter quelqu'un qui ne maîtrise pas parfaitement Java:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
39
Rasmus Faber

En dépit du fait que cette question a été posée il y a longtemps, mais je pense qu'une description complète permettrait de comprendre pourquoi il n'est pas nécessaire d'utiliser l'abrégé public avant méthodes et public statique final 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 remplacé par d'autres classes.

Deuxièmement, Bien que l'on puisse initier des objets d'un type d'interface, une interface est réalisée par les classes qui l'implémentent et n'est pas héritée. Et puisqu’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 paquet, le modificateur d’accès protégé n’est donc pas valide non plus. Donc, pour le modificateur d'accès, il ne reste que le choix du public.

Troisièmement, une interface ne comporte aucune implémentation de données, y compris les variables d'instance et les méthodes. S'il existe 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, aucune méthode ne pouvant être implémentée dans une interface, toutes les méthodes de l'interface doivent donc être abstraites. 

Quatrièmement, Interface ne peut inclure que constant en tant que données membres, ce qui signifie qu'elles doivent être finales. Bien entendu, les constantes finales sont déclarées statiques pour ne conserver qu'une instance. Par conséquent, static final est également indispensable pour les constantes d'interface.

Donc, en conclusion, bien que l’utilisation de abstract public avant méthodes et de public static final avant constantes d’une interface soit valide, mais comme il n’existe aucune autre option, elle est considérée comme redondante et non utilisée. 

8
Leo The Four

J'éviterais de mettre des modificateurs qui sont 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...

5
PhiLho

J'ai utilisé des méthodes de déclaration avec le modificateur public, 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 pour les modificateurs public sur les méthodes d'interface. Je suis donc passé à les omettre.

Donc, je ne suis pas vraiment sûr de ce qui est le mieux, mais une chose que je n'aime pas vraiment utilise public abstract sur les méthodes d'interface. Eclipse le fait parfois lors du refactoring avec "Extract Interface".

5
cretzel

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

4
JeeBee

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. Elle est publique par défaut pour que la classe d'implémentation puisse y accéder.

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.

3
Iuliana Cosmina

Je préfère le sauter, je lis quelque part que les interfaces sont par défaut, public et abstract

À ma grande surprise, le livre - Head First Design Patterns , utilise public avec une déclaration d'interface et des méthodes d'interface ... qui m'a fait repenser une fois encore et j'ai atterri sur ce message. 

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

3
Pradeep Sharma

Avec l'introduction des modificateurs private, static, default pour les méthodes d'interface en Java 8/9, les choses deviennent plus compliquées et j'ai tendance à penser que les déclarations complètes sont plus lisibles (nécessite la compilation de Java 9):

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

}
3
Werner Thumann

C'est totalement subjectif. J'omets le modificateur redondant public 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é de l'appliquer. Déclarer une méthode d'interface publique en C # est en réalité une erreur de compilation. La cohérence n’est probablement pas importante d’une langue à l’autre, donc je suppose que cela n’est pas directement pertinent pour Java.

1
serg10

Je ne suis pas d’accord avec la réponse populaire, selon laquelle avoir un public implique qu’il existe d’autres options et qu’elles ne devraient donc pas exister. Le fait est qu’à présent avec Java 9 et au-delà, il existe d’autres options.

Je pense plutôt que Java devrait imposer/exiger que «public» soit spécifié. Pourquoi? Parce que l’absence de modificateur signifie que l’accès au «paquet» est utilisé partout ailleurs et c’est un cas particulier qui crée la confusion. Si vous faites simplement une erreur de compilation avec un message clair (par exemple, "L’accès à un package n’est pas autorisé dans une interface"), nous éliminerions l’ambiguïté apparente que peut avoir l’option de laisser de côté «public».

Notez le libellé actuel à l’adresse: 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 public ou Private (§6.6). Si aucun modificateur d'accès n'est fourni, la méthode est implicitement publique. Elle est autorisée mais déconseillée. en tant que style , spécifier de manière redondante le modificateur public pour une déclaration de méthode dans une interface. "

Voir que 'privé' IS est autorisé maintenant. Je pense que cette 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 la compatibilité avec les versions antérieures et entraînera la confusion que l'absence du modificateur d'accès signifie "public" dans les interfaces et "package" ailleurs.

0
swpalmer