118 votes

Classe interne à l'interface

Est-il possible de créer un classe intérieure au sein d'une interface ?
Si c'est possible, pourquoi voudrions-nous créer une classe intérieure comme ça, puisque nous n'allons pas créer d'objets d'interface ?

Est-ce que ces classes intérieures aider dans tout processus de développement ?

121voto

zafar142003 Points 30

Oui, on peut avoir des classes à l'intérieur d'interfaces. Un exemple d'utilisation pourrait être

public interface Input
{
    public static class KeyEvent {
         public static final int KEY_DOWN = 0;
         public static final int KEY_UP = 1;
         public int type;
         public int keyCode;
         public char keyChar;
    }
    public static class TouchEvent {
         public static final int TOUCH_DOWN = 0;
         public static final int TOUCH_UP = 1;
         public static final int TOUCH_DRAGGED = 2;
         public int type;
         public int x, y;
         public int pointer;
    }
    public boolean isKeyPressed(int keyCode);
    public boolean isTouchDown(int pointer);
    public int getTouchX(int pointer);
    public int getTouchY(int pointer);
    public float getAccelX();
    public float getAccelY();
    public float getAccelZ();
    public List<KeyEvent> getKeyEvents();
    public List<TouchEvent> getTouchEvents();
}

Ici, le code comporte deux classes imbriquées qui servent à encapsuler des informations sur les objets d'événements qui sont ensuite utilisés dans les définitions de méthodes comme getKeyEvents(). Le fait de les avoir à l'intérieur de l'interface Input améliore la cohésion.

3 votes

@Levit Je me demande juste à quoi ressemblera la classe implémentée ?

1 votes

J'aimerais bien voir une mise en œuvre en action pour l'utilisation ci-dessus. Merci.

60voto

SyntaxT3rr0r Points 10771

Oui, vous peut créer à la fois une classe imbriquée ou une classe interne à l'intérieur d'une interface Java (notez que, contrairement à la croyance populaire, il n'existe pas de classe " classe interne statique "Il n'y a pas de classe "intérieure" ni de classe "extérieure" lorsqu'une classe imbriquée est statique, elle ne peut donc pas être "statique intérieure").

Quoi qu'il en soit, ce qui suit se compile bien :

public interface A {
    class B {
    }
}

Je l'ai vu utilisé pour mettre une sorte de "vérificateur de contrat" directement dans la définition de l'interface (enfin, dans la classe imbriquée dans l'interface, qui peut avoir des méthodes statiques, contrairement à l'interface elle-même, qui ne le peut pas). Cela ressemble à ceci si je me souviens bien.

public interface A {
    static class B {
        public static boolean verifyState( A a ) {
            return (true if object implementing class A looks to be in a valid state)
        }
    }
}

Notez que je ne me prononce pas sur l'utilité d'une telle chose, je réponds simplement à votre question : c'est possible et c'est un type d'utilisation que j'ai vu.

Maintenant, je ne vais pas commenter l'utilité d'une telle construction et de ce que j'ai vu : Je l'ai vu, mais ce n'est pas une construction très courante.

Nous avons ici une base de code de 200KLOC où cela n'arrive jamais (mais il y a beaucoup d'autres choses que nous considérons comme des mauvaises pratiques qui n'arrivent jamais et que d'autres personnes trouveraient parfaitement normales, donc...).

0 votes

Pouvez-vous ajouter quelques exemples d'utilisation ? J'ai testé quelque chose de similaire il y a quelque temps et je n'ai pas compris ce que je pouvais gagner en utilisant cette construction.

0 votes

@Roman : Je me souviens avoir rencontré cela sur certains projets (des projets relativement propres d'ailleurs mais ce n'était pas les miens) mais je ne sais pas si c'est vraiment propre ou non. J'ai ajouté un petit exemple qui ressemble à ce que j'ai vu mais encore une fois : ce n'était pas mon code et je n'utilise pas cette construction donc je ne suis pas le plus qualifié pour proposer des exemples valides :) IIRC la classe à l'intérieur était toujours nommée, par exemple StateChecker et les appels ressembleraient toujours à : A.StateChecker.check( a ) ou quelque chose comme ça.

11 votes

Si vous dites qu'il n'y a pas de " classe interne statique "" votre réponse que "vous peut créer à la fois une classe imbriquée ou une classe interne à l'intérieur d'une interface Java" est fondamentalement faux. En utilisant votre définition restreinte, interface s peuvent pas ont des classes internes. Vous pouvez omettre le static modificateur d'un interface C'est une classe imbriquée, mais c'est quand même une classe imbriquée, pas une classe interne.

49voto

helios Points 8379

Une utilisation valide, à mon avis, consiste à définir les objets qui sont reçus ou renvoyés par les méthodes de l'interface englobante. En général, il s'agit de structures de stockage de données. De cette façon, si l'objet n'est utilisé que pour cette interface, les choses sont plus cohérentes.

Par exemple :

interface UserChecker {
   Ticket validateUser(Credentials credentials);

   class Credentials {
      // user and password
   }

   class Ticket {
      // some obscure implementation
   }
}

Mais de toute façon... c'est seulement une question de goût.

12voto

Bachi Points 2009

Un cas d'utilisation intéressant consiste à fournir une sorte d'implémentation par défaut des méthodes de l'interface par le biais d'une classe interne, comme décrit ici : https://stackoverflow.com/a/3442218/454667 (pour surmonter le problème de l'héritage à classe unique).

2 votes

Et c'est exactement pourquoi les classes de membres privés auraient un sens.

1voto

SlowStrider Points 274

Ce que @Bachi mentionne est similaire aux traits en Scala et est en fait implémenté en utilisant une classe imbriquée dans une interface. Cela peut être simulé en Java. Voir aussi le modèle des traits ou mixins java ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X