35 votes

Quel est l'avantage d'avoir des classes internes statiques publiques d'une interface / classe?

J'ai remarqué que le code suivant modèle pendant la navigation par le biais de certaines sources de mon projet de la 3e partie des bibliothèques:

public interface MyInterface {
    public static class MyClass1 implements MyInterface { ... }
    public static class MyClass2 implements MyInterface { ... }
    public static class MyClass3 implements MyInterface { ... }
}

Ou bien celle-ci:

public class MyBaseClass {
    public static class MyClass1 extends MyBaseClass { ... }
    public static class MyClass2 extends MyBaseClass { ... }
    public static class MyClass3 extends MyBaseClass { ... }
}

Exemples concrets:

  • SwingX: org.jdesktop.swingx.decorator.HighlightPredicate (Source)
  • Substance: org.pushingpixels.substance.api.renderers.SubstanceDefaultTableCellRenderer (Source)

Quel est l'avantage d'avoir une structure de code de ce genre?

Ma première pensée a été "agrégation", mais la même chose pourrait être réalisé à l'aide de la plaine de vieux paquets. Alors, quand/pourquoi est-il mieux d'utiliser les classes internes au lieu d'un paquet?

17voto

codevour Points 3246

Je pense que cela est motivé par l'agrégation, ils sont peut-être aussi pas la peine de créer une classe de haut niveau. Je le fais parfois, si quelque chose est à petit pour créer un package (pour les séparer des autres), mais les classes correspondantes ne doivent être utilisés dans le contexte de la classe de haut niveau. À mon avis, c'est une décision de conception.

Le décorateur modèle peut-être un bon exemple, ils peuvent être appliqués sur le haut-niveau de la classe, mais sont peut-être tellement simple qu'ils ne sont pas la peine d'être aussi haut niveau. Vous pouvez facilement afficher la propriété en les utilisant comme des classes internes.

Ce n'est pas visible au premier coup d'œil avec les paquets. Vous voir directement dépendante de la classe/de l'interface.

De plus, il est possible d'accéder aux champs privés de la classe, ce qui peut être utile et est plus fine que le colis privé champ d'application.

10voto

Péter Török Points 72981

Une utilisation à laquelle je peux penser est de fournir des implémentations prêtes à l'emploi de l'interface, accessibles à tous, mais toujours liées conceptuellement à l'interface mère.

Cela n'a de sens que si l'interface est simple (les classes d'implémentation internes sont donc petites), il n'y en a pas beaucoup et la plupart des clients d'interface en ont réellement besoin. Sinon, ils encombrent le fichier source, le rendant plus difficile à comprendre.

4voto

Grzegorz Oledzki Points 10491

En ce qui concerne les classes et leurs classes internes (ne s'applique pas aux interfaces), une différence réside dans le fait que les classes internes peuvent utiliser des membres privés de la classe externe, ce qui n'est pas le cas si elles étaient des «frères et sœurs» (niveau supérieur séparé). Des classes).

Exemple:

 public class MyBaseClass {

    private static String staticField = "outer";

    public static class MyClass1 extends MyBaseClass { 

      public MyClass1() {
          MyBaseClass.staticField = "inner1";
      }

    }
}
 

Cela ne fonctionnera pas si vous avez déplacé les MyClass de la classe externe.

1voto

developer Points 2924

Une interface interne doit être statique pour être accessible. L'interface n'est pas associée aux instances de la classe, mais à la classe elle-même, elle serait donc accessible avec Foo.Bar, comme suit:

1voto

Ingo Points 21438

En procédant ainsi, vous pourrez économiser des fichiers de code source supplémentaires et donner à la classe un joli nom hiérarchique, par exemple, org.foo.bar.XY.Default au lieu de org.foo.bar.DefaultXY.

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