web-dev-qa-db-fra.com

Quand utiliser les classes internes dans Java pour les classes d'assistance

Si j'ai par exemple une classe avec une classe auxiliaire pour faire certaines de ses fonctionnalités, est-il sensé d'en faire une classe interne.

    public class Foo {
       private FooHelper helper;

       // constructor & any other logic

       public void doSomeThing() {
         helper.do();
       }
    }

    public class FooHelper {
        public void do() {
         // code
        }
    }

Dans le cas ci-dessus, est-il judicieux de faire du FooHelper une classe interne? Toutes mes excuses si cela semble stupide mais je suis peu confus quant aux cas d'utilisation.

51
Hild

Oui, il est parfaitement logique d'en faire une classe intérieure. Si aucune autre classe n'en a besoin, rendez-la privée. Si elle ne nécessite pas un accès exclusif aux membres de la classe externe, faites-en une classe imbriquée statique car elle nécessitera alors moins d'espace mémoire.

Consultez la recommandation de le tutoriel officiel -

Utilisez une classe imbriquée non statique (ou classe interne) si vous avez besoin d'accéder aux champs et méthodes non publics d'une instance englobante. Utilisez une classe imbriquée statique si vous n'avez pas besoin de cet accès.

55
MD Sayem Ahmed

Si vous pensez que FooHelper sera pas du tout utile pour d'autres classes que Foo, alors il est logique de le faire comme private classe interne de Foo. Un exemple de ce type de conception peut être trouvé dans HashMap où il définit une classe interne privée KeySet

Sinon, l'avoir comme une instance private semble bon.

14
sanbhat

De Java Docs SE

Pourquoi utiliser des classes imbriquées?

C'est une façon de regrouper logiquement des classes qui ne sont utilisées qu'à un seul endroit: Si une classe n'est utile qu'à une autre classe, alors il est logique de l'intégrer dans cette classe et de garder les deux ensemble. L'imbrication de ces "classes d'assistance" rend leur package plus rationalisé.

Cela augmente l'encapsulation: Considérons deux classes de niveau supérieur, A et B, où B a besoin d'accéder aux membres de A qui seraient autrement déclarés privés. En cachant la classe B dans la classe A, les membres de A peuvent être déclarés privés et B peut y accéder. De plus, B lui-même peut être caché du monde extérieur.

Alors oui, il est logique d'utiliser FooHelper comme classe interne.

12
ChandraBhan Singh

Voici quelques utilisations des classes internes.

  • Les classes internes sont utilisées pour obtenir des fonctionnalités qui peuvent obtenir un objet mieux qu'une méthode.
  • Ils peuvent être utilisés dans le cas où un ensemble de plusieurs opérations est requis et les chances de réutilisation sont bonnes à l'intérieur de la classe et elles ne seront pas accessibles mais des méthodes en dehors de la classe externe.
  • Les classes internes sont également conçues pour obtenir un héritage multiple.
  • Les classes internes sont utilisées lorsqu'elles sont utiles dans le contexte d'une classe.
  • Ils sont utilisés pour séparer la logique à l'intérieur des classes.

Donc, si vous avez des exigences correspondant aux points ci-dessus, les classes internes peuvent être utilisées. Il est toujours préférable de faire de la classe interne private pour empêcher l'accès aux autres classes. Dans votre cas, l'utilisation de classes internes est utile pour rendre le code lisible et séparé dans la classe externe.

6
Ashwani

Les classes internes ont du sens quand elles sont minuscules et n'ont pas besoin de noms. Les écouteurs dans les interfaces graphiques sont des exemples classiques où ils ont un sens.

Si la classe est grande et importante, elle doit être nommée et placée dans un fichier séparé.

Les classes d'écoute dans les exemples GUI normaux font une toute petite chose, généralement simplement réparties sur une autre fonction pour faire un vrai travail.

J'utilise aussi souvent des classes imbriquées statiques (qui ne sont techniquement pas des classes internes) pour des classes qui ne sont utilisées que dans le contexte d'une autre classe - Map.Entry en est un bon exemple. Il n'est utilisé qu'en conjonction avec une carte, donc la définition de l'entrée doit faire partie de l'interface de la carte est logique pour l'organisation.

Je n'ai généralement pas beaucoup d'utilisation pour d'autres types de classes imbriquées, comme les classes membres non statiques et les classes locales. Mais ils sont parfois utiles. Pour un bon exemple d'utilisation légitime des classes membres, consultez le code source de LinkedList.ListItr. Il s'agit d'une classe interne privée dont le but est de fournir une implémentation de ListIterator pour un LinkedList . Pour ce faire, il est utile d'avoir accès aux données privées à l'intérieur de la LinkedList. Pour y parvenir en utilisant uniquement des classes de niveau supérieur, il aurait fallu exposer davantage de méthodes publiques dans LinkedList pour permettre à ListIterator d'accéder à l'implémentation sous-jacente de LinkedList. Au lieu de cela, l'utilisation d'une classe interne permet à LinkedList de garder son implémentation privée, comme il se doit.

1
code_fish

Oui, l'avantage d'utiliser la classe interne est qu'elle peut accéder aux membres de la classe externe. Dans votre cas, si vous pensez que votre FooHelper ne doit pas être utilisé par une autre classe, vous pouvez en faire une classe interne.

Pour vérifier l'utilité de la classe interne, parcourez les exemples d'AWT. Les classes internes anonymes sont largement utilisées dans les gestionnaires d'événements.

1
Malwaregeek

Quelle est la portée de Foo? Lorsque Foo est classe de modèle de domaine avec son propre cycle de vie et helper est un service commun, cela ressemble à mélanger deux objets avec une portée/un cycle de vie très différents.

En règle générale, l'entité de domaine a son propre cycle de vie depuis la création, la persistance jusqu'à son GC. D'autre part, l'aide ou le service est soit statique, soit meilleur dynamique avec un cycle de vie égal à l'ensemble de l'application, par ex. haricot de printemps.

Une fois que votre entité de domaine contiendrait la référence d'un service, cela peut vous poser de sérieux problèmes. Par exemple. chaque appel au Get du référentiel doit injecter la référence de ce service dans l'entité de domaine. Je recommanderais d'éviter ce modèle.

Il n'est pas évident pour moi qui fera l'instance de Helper pour vous.

0
Martin Podval

Hild, oui, il est logique d'utiliser une classe interne dans de nombreux cas.

Pensez-y de cette façon - la classe interne vivra et mourra avec la classe externe, de sorte que toute fonctionnalité spécifiquement requise pour la classe externe peut être ajoutée à la classe interne. Les exemples les plus courants sont: - les écouteurs dans la plupart des cas - les types d'écouteurs clés, d'écouteurs souris, d'écouteurs d'événements.

Les classes dans Java vous permettent d'avoir des fonctionnalités spécifiques, mais parfois vous devrez peut-être avoir une fonctionnalité spécialisée distincte mais elle doit également être intimement liée à la classe que vous concevez.

Il peut y avoir quatre types de classes internes. Une simple recherche sur Google peut vous aider à en savoir plus à leur sujet.

0
Ravindra Mijar

Selon Oracle Docs, simplement expliqué

Les raisons impérieuses d'utiliser des classes imbriquées sont les suivantes:

C'est une façon de regrouper logiquement des classes qui ne sont utilisées qu'à un seul endroit: Si une classe n'est utile qu'à une autre classe, alors il est logique de l'intégrer dans cette classe et de garder les deux ensemble. L'imbrication de ces "classes d'assistance" rend leur package plus rationalisé.

Cela augmente l'encapsulation: Considérons deux classes de niveau supérieur, A et B, où B a besoin d'accéder aux membres de A qui seraient autrement déclarés privés. En cachant la classe B dans la classe A, les membres de A peuvent être déclarés privés et B peut y accéder. De plus, B lui-même peut être caché du monde extérieur.

Cela peut conduire à un code plus lisible et maintenable: L'imbrication de petites classes dans des classes de niveau supérieur rapproche le code de son utilisation.

0
nitinsridar

Les classes imbriquées vous permettent de grouper logiquement les classes qui ne sont utilisées qu’en un seul endroit, d’augmenter l’utilisation de l’encapsulation et de créer du code plus lisible et plus facile à gérer. Cours locaux, cours anonymes.

http://docs.Oracle.com/javase/tutorial/Java/javaOO/whentouse.html

0
Rahul Maurya

Quand utiliser les classes internes?

  1. La classe interne n'a besoin d'aucun fichier supplémentaire ou séparé pour être placé.
  2. Les classes internes sont relativement petites et étroitement couplées avec la classe "parent" ou la classe "externe". Évite beaucoup de classes d'assistance et convient pour expliquer le principe de confinement OOD.
  3. Tout le code dans le même fichier augmente la lisibilité et augmente les performances (comme le code en ligne). Leur importance augmente dans le codage et est considérée comme une bonne pratique.
  4. Les classes internes anonymes sont très utiles lorsque vous souhaitez définir des rappels à la volée.
  5. Un objet d'une classe interne peut accéder à l'implémentation de l'objet qui l'a créé - Y COMPRIS les données privées.
  6. Les classes internes sont capables d'accéder au comportement de leur classe parent, y compris private.
0
Premraj