web-dev-qa-db-fra.com

Champs dans les interfaces

J'ai une question de base en Java, mais c'est une question générale en POO. Pourquoi les interfaces permettent-elles de définir des champs? Cela ne va-t-il pas à l'encontre de ce qu'une interface est censée faire?

D'après ce que j'ai compris, une interface est ce qui en anglais serait un adjectif. Donc, si ma classe implémente les interfaces Runnable et Serializable, je garantis à l'utilisateur que ma classe remplira les conditions pour être Runnable et Seriablizable. Cependant, cela signifierait que les interfaces sont "sans état", mais elles sont autorisées à avoir des champs en Java ...

Suis-je en train de manquer quelque chose?

46
Sal

Tous les champs de l'interface sont public static final, c'est-à-dire que ce sont des constantes.

Il est généralement recommandé d'éviter de telles interfaces, mais parfois vous pouvez trouver une interface qui n'a pas de méthodes et qui est utilisée uniquement pour contenir la liste des valeurs constantes.

55
Andrew Logvinov

Tout d'abord, il y a une différence entre paradigme OOP et implémentation OOP en Java, donc les mêmes mots peuvent signifier des choses un peu différentes.

Dans OOP l'interface du paradigme est ce que vous pouvez faire avec l'objet (ou ce que l'objet peut faire pour vous). Tout objet peut avoir plusieurs interfaces et jouent ainsi des rôles différents. Par exemple, quelqu'un peut travailler comme programmeur et être capable de créer des programmes, mais en même temps il peut être mari et père et donc être en mesure de payer les factures de sa famille et de prendre soin des enfants. Ici "programmeur", "mari" et "père" sont des interfaces, et une personne est un objet qui les implémente. Notez, que les interfaces n'impliquent pas la présence de fonctionnalités spécifiques (champs) pour implémenter l'objet, juste des actions qui cet objet devrait être capable de fonctionner.

Java suit plus ou moins cette idée, mais comme toute implémentation de paradigme a ses propres caractéristiques. Java permet de décrire les méthodes, c'est-à-dire les actions que l'objet d'implémentation devrait être capable d'exécuter, mais pas les détails d'implémentation, donc rien sur les champs d'objet ou les méthodes privées.

Mais qu'en est-il de constantes (public final static des champs)? Font-ils partie de l'implémentation ou de l'interface. Ça pourrait être les deux. Par exemple. l'interface "programmeur" peut avoir une constante WORK_HOURS réglé sur "8". Ainsi Java vous permet également de décrire des constantes dans les interfaces.

Notez que Java ne vous aide qu'à améliorer la conception OOP, mais il ne l'exige pas fortement. En particulier, toutes les méthodes publiques d'un objet ne sont pas Par exemple, les méthodes getter et setter sont normalement publiques, mais en fait ce sont les partie de l'implémentation, pas l'interface, et donc il vaut la peine de ne pas les mettre en interface.

(Veuillez également noter que la plupart des choses que j'ai décrites ici concernent le courant principal OOP comme en Java, mais il existe également d'autres types de OOP tels que ceux basés sur des prototypes). un, notamment implémenté en JavaScript).

20
ffriend

Et si cette interface fait référence à des constantes? Ne serait-il pas naturel de les déclarer dans l'interface?

interface IdFinder {
    Serializable UNSAVED = new Serializable() {};

    /** @returns the given entity's persistent identity, 
                 or {@link UNSAVED} if it hasn't been saved yet, 
                 or null if o is a value object that hasn't a 
                 persistent identity of its own.
     */
    Serializable getId(Object o);
}
4
meriton

Oui, vous pouvez avoir des champs constants dans les interfaces, mais vous avez raison quand vous dites que "cela semble contraire à ce qu'une interface est censée faire", car ce n'est pas une bonne pratique. Pourquoi voudriez-vous que toutes vos classes implémentent une interface avec les mêmes constantes? Vous pouvez simplement les avoir dans la classe qui les utilise, ou si vous avez vraiment besoin de les exporter d'une manière ou d'une autre, les avoir dans une classe distincte comme celle-ci:

public class Constants {
    private Constants() { }

    public static final int ZERO = 0;
    public static final int SOME_COMPLEX_NUM = 2124132L;
    ...
}

Vous avez également des énumérations, si vous devez représenter un ensemble de champs constants ayant une certaine signification. Je ne vois aucun "cas d'utilisation" où vous auriez réellement besoin de constantes dans une interface. Mais pourrait se tromper :)

2
jlemos