web-dev-qa-db-fra.com

À quoi servent les classes internes

J'examine le concept de classes internes en Java. si loin de ce que j'ai compris et appliqué Java les classes internes ont un lien ou un accès aux méthodes et champs de sa classe externe/englobante.

Ma question:

  1. Quand faut-il créer ou définir une classe interne?
  2. les classes internes sont-elles considérées comme des "classes auxiliaires"?
  3. Quels sont les indicateurs pour vous de faire une classe intérieure et quel est leur autre objectif?
44
user962206

Les classes internes sont idéales pour regrouper logiquement les classes utilisées en un seul endroit. Par exemple, si vous souhaitez créer une classe qui est utilisée par SEULEMENT la classe englobante, cela n'a aucun sens de créer un fichier distinct pour cela. Au lieu de cela, vous pouvez l'ajouter en tant que "classe interne"

Selon tutoriel Java :

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'en un seul endroit.
  • Il augmente l'encapsulation.
  • Cela peut conduire à un code plus lisible et plus facile à gérer.
41
kosa

Une utilisation classique pour une classe interne est l'implémentation d'un itérateur à l'intérieur d'un conteneur ( ArrayList , par exemple - recherchez class Itr). Tout ce que le conteneur veut exposer au reste du monde est un Iterator. Cependant, il doit créer une implémentation concrète de cet itérateur, peut-être familier avec les internes du conteneur. L'utilisation d'une classe interne masque l'implémentation, tout en la maintenant proche de l'implémentation du conteneur. Et étant interne (c'est-à-dire non statique), il est lié à une instance spécifique de ce conteneur, ce qui lui permet d'accéder aux membres de conteneur privés.

Il existe quelques types de classes internes - classe imbriquée non statique, classes locales et classes anonymes. Chacun a un objectif quelque peu différent, donc lorsque vous posez des questions sur une classe interne, vous devez spécifier de quel type vous parlez.

En supposant que vous faites référence à des classes internes non statiques, je dirais que la raison de les utiliser est la même que l'utilisation de classes régulières (à savoir l'abstraction et la division du code en unités logiques), mais il n'y a aucune raison de rendre visible cette utilisation des classes au reste du monde. Vous pouvez également rendre les classes imbriquées publiques, bien sûr, auquel cas vous les rendriez imbriquées au lieu d'être indépendantes afin d'exprimer leur relation étroite avec la classe externe.

14
eran
  1. Voir le tutoriel Java pour les raisons principales.

  2. Si par "classe d'assistance" vous voulez dire quelque chose pour un usage interne uniquement, alors non, pas nécessairement. Vous voudrez peut-être faire quelque chose comme

    class Outer {
        private static class Inner implements InterestingInterface {
            // whatever
        }
        public InterestingInterface make_something_interesting() {
            return new Inner();
        }
    }
    

    Ici, Inner n'est pas une "classe d'assistance" dans le sens où le monde extérieur peut en voir des instances, mais son implémentation est entièrement cachée - le monde extérieur sait seulement qu'il obtient un objet qui implémente InterestingInterface.

4
Fred Foo

L'un des objectifs des classes internes est d'attacher des auditeurs. Par exemple, supposons que vous ayez un JMenuItem. Vous pouvez le faire quitter votre application comme indiqué dans ce code:

JMenuItem quitItem = new JMenuItem("Quit");
quitItem.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e)
    {
        //cleanup code before exiting
        System.exit(0);
    }
});

Vous pouvez également souhaiter qu'une classe ait accès aux variables d'état de classe externes qui sont entièrement subordonnées à cette classe. Par exemple, envisagez d'écrire une simple calculatrice de couleurs. Il peut avoir une zone de texte dans laquelle vous tapez un code hexadécimal. Lorsque vous appuyez sur Entrée, vous souhaitez qu'un JPanel affiche la couleur. Voici un aperçu sommaire de ce que vous pourriez faire.

public class ColorCalc extends JPanel implements Runnable
{
    Color displayedColor;
    JTextArea colorEnterArea;
    public ColorCalc()
    {
        displayedColor = Color.white
        colorEnterArea = new JTextArea();
    }
    public void run()
    {
        //build GUI here
    }
    public static void main(String[] args)
    {
         ColorCalc cc = new ColorCalc();
         javax.swing.SwingUtilities.invokeLater(cc);
    }
    //subservient inner class with access to outer class state variable.
    class ColorPanel extends JPanel
    {
         public void paintComponent(Graphics g)
         {
             g.setColor(displayedColor);
             g.fillRect(0,0,getWidth(), getHeight());
         } 
    }

}
3
ncmathsadist

En règle générale, objets doit être conçu pour une responsabilité unique (Hautement cohésif ). En d'autres termes, tout objet bien conçu doit effectuer une tâche cohérente unique. Cela serait considéré comme la meilleure pratique pour la conception orientée objet.

Parfois, cependant, un développeur peut concevoir une classe qui nécessite une classe distinctespécialisée pour fonctionner. Cette classe séparée spécialisée pourrait être considérée comme une classe auxiliaire.

Si la classe d'aide est non utilisée par une autre classe, alors elle serait considérée comme candidat principal comme classe interne

Comme indiqué par ncmathsadist ci-dessus, un exemple d'utilisation de classe interne se trouverait dans l'implémentation de gestionnaires d'événements.

Par exemple, lors de la conception d'une interface utilisateur graphique (GUI), un développeur peut avoir créé un bouton que exécute a particulier tâche après que l'utilisateur a appuyé dessus.

Le bouton aurait besoin d'un gestionnaire d'événements qui écoute lorsque ce bouton particulier est enfoncé.

Dans ce cas, la création du gestionnaire d'événements pour le bouton en tant que classe interne serait la meilleure pratique car la classe interne ne le serait pas être utilisé ailleurs qu'avec le bouton spécifique dans la classe GUI.

3
Mark Burleigh

Si vous trouvez qu'il y a suffisamment de code qui pourrait être mieux fait par classe car la classe nous fournit pour spécifier les statistiques et le comportement avec les champs et les méthodes et que vous ne voulez pas que cette classe doive être utilisée en dehors de la classe englobante. vous devez utiliser la classe interne.

Ici, la classe intérieure est cachée du monde extérieur. La classe interne peut accéder au membre privé de la classe englobante qui nous fournit l'encapsulation.

Permettez-moi de donner un exemple. Supposons que vous vouliez régler l'engrenage sur cycle et que vous ayez une règle commerciale comme il n'y a que jusqu'à 6 vitesses. Vous pouvez donc créer un cycle de classe interne qui aurait une méthode pour régler l'engrenage. Cette méthode a une certaine validation qui est vérifiée avant de régler la vitesse.Comme le cycle est en cours ... le nombre de vitesse est inférieur à 6 ...

le meilleur exemple est que le code de gestion des événements utilise des classes internes (parfois des classes internes anonymes) pour créer des événements et des écouteurs sans créer des classes d'objet d'événement et d'écouteur d'événement distinctes pour votre événement.

2
027

C'est une question de style. Tout ce qui peut être fait avec une classe interne peut également être fait comme une série de classes externes. Les classes internes sont particulièrement utiles pour les classes qui sont légères ou étroitement liées à la classe englobante. Par exemple, un comparateur est souvent ces deux choses. Il a besoin d'une connaissance approfondie de l'implémentation de la classe et peut ne comporter que quelques lignes. Ce peut être un candidat idéal en tant que classe interne.

1
Spina

La classe interne utilisée pour regrouper la logique des classes, par exemple, si vous avez la classe B et cette classe utilisée uniquement à la classe A, il est donc préférable de mettre la classe B en tant que classe interne à la classe A, car cela donnera la lisibilité et la réutilisabilité pour votre code.

Code heureux :)

0
Mohamed Ali