JavaRush /Blog Java /Random-FR /Cours anonymes en Java

Cours anonymes en Java

Publié dans le groupe Random-FR
Bonjour! Dans la leçon d'aujourd'hui, nous continuerons à aborder le sujet des classes imbriquées. C'est au tour du dernier groupe - les classes internes anonymes en Java. Revenons à notre schéma : Cours anonymes - 2comme les classes locales dont nous avons parlé dans le cours précédent, les classes anonymes sont un sous-ensemble des classes internes. Ils présentent également plusieurs similitudes et différences entre eux. Mais d’abord, voyons cela : pourquoi sont-ils réellement appelés « anonymes » ? Pour ce faire, regardons un exemple simple. Imaginez que nous ayons un programme principal qui s'exécute et fait constamment quelque chose. Nous souhaitons créer un système de suivi de ce programme composé de plusieurs modules. Un module surveillera les indicateurs de performance généraux et tiendra un journal, le second enregistrera et enregistrera les erreurs dans le journal des erreurs, le troisième surveillera les activités suspectes : par exemple, les tentatives d'accès non autorisées et d'autres éléments liés à la sécurité. Étant donné que les trois modules doivent essentiellement démarrer au début du programme et s'exécuter en arrière-plan, c'est une bonne idée de créer une interface commune pour eux :
public interface MonitoringSystem {

   public void startMonitoring();
}
Il sera mis en œuvre par 3 classes spécifiques :
public class GeneralIndicatorsMonitoringModule implements MonitoringSystem {

@Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }
}


public class ErrorMonitoringModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Bug Tracking Monitoring Started!");
   }
}


public class SecurityModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Security monitoring started!");
   }
}
Il semblerait que tout soit en ordre. Nous avons un système assez clair de plusieurs modules. Chacun d'eux a son propre comportement. Si nous avons besoin de nouveaux modules, nous pouvons les ajouter, car nous disposons d’une interface assez simple à mettre en œuvre. Mais réfléchissons au fonctionnement de notre système de surveillance. Cours anonymes - 3Essentiellement, nous devrions simplement créer 3 objets - GeneralIndicatorsMonitoringModule, ErrorMonitoringModule, SecurityModule- et appeler une méthode startMonitoring()sur chacun d'eux. Autrement dit, tout ce que vous avez à faire est de créer 3 objets et d’appeler 1 méthode dessus.
public class Main {

   public static void main(String[] args) {

       GeneralIndicatorsMonitoringModule generalModule = new GeneralIndicatorsMonitoringModule();
       ErrorMonitoringModule errorModule = new ErrorMonitoringModule();
       SecurityModule securityModule = new SecurityModule();

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
Sortie de la console :

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
Et pour un si petit travail, nous avons écrit tout un système : 3 classes et une interface ! Et tout cela pour 6 lignes de code. D’un autre côté, quelles sont nos options ? Oui, ce n'est pas très cool que nous ayons écrit des cours aussi « jetables ». Mais comment pouvons-nous résoudre ce problème ? C'est là que les classes internes anonymes nous viennent en aide ! Voici à quoi ils ressemblent dans notre cas :
public class Main {

   public static void main(String[] args) {

       MonitoringSystem generalModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Monitoring of general indicators has started!");
           }
       };



           MonitoringSystem errorModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Bug Tracking Monitoring Started!");
           }
       };

       MonitoringSystem securityModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Security monitoring started!");
           }
       };

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
Voyons ce qui se passe ici ! Il semble que nous créons un objet d'interface :
MonitoringSystem generalModule = new MonitoringSystem() {

@Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }
};
Mais on sait depuis longtemps qu’il est impossible de créer des objets d’interface ! C'est vrai, c'est impossible. En fait, nous ne le faisons pas. Au moment où nous écrivons :
MonitoringSystem generalModule = new MonitoringSystem() {

};
À l'intérieur de la machine Java, les événements suivants se produisent :
  1. Une classe Java sans nom est créée pour implémenter le MonitoringSystem.
  2. Le compilateur, voyant une telle classe, vous oblige à implémenter toutes les méthodes de l'interface MonitoringSystem(nous l'avons fait 3 fois).
  3. Un objet de cette classe est créé. Faites attention au code :
MonitoringSystem generalModule = new MonitoringSystem() {

};
Il y a un point-virgule à la fin ! Elle est là pour une raison. Nous déclarons simultanément une classe (via des accolades) et créons son objet en utilisant (); Chacun de nos trois objets a surchargé une méthode startMonitoring()à sa manière. A la fin on appelle simplement cette méthode sur chacun d'eux :
generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
Sortie de la console :

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
C'est tout! Nous avons terminé notre tâche : nous avons créé trois objets MonitoringSystem, l'avons redéfini de trois manières différentes et l'avons appelé trois fois. Les trois modules sont lancés et fonctionnent avec succès. En même temps, la structure de notre programme est devenue beaucoup plus simple ! GeneralIndicatorsMonitoringModuleAprès tout , les classes peuvent ErrorMonitoringModuledésormais SecurityModuleêtre complètement supprimées du programme ! Nous n’en avons tout simplement pas besoin – nous nous en sommes très bien sortis sans eux. Si chacune de nos classes de modules anonymes a besoin d'un comportement différent, de ses propres méthodes spécifiques que les autres n'ont pas, nous pouvons facilement les ajouter :
MonitoringSystem generalModule = new MonitoringSystem() {

   @Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }

   public void someSpecificMethod() {

       System.out.println("Specific method for first module only");
   }
};
La documentation Oracle contient une bonne recommandation : "Utilisez des classes anonymes si vous avez besoin d'une classe locale pour un usage unique." Une classe anonyme est une classe interne à part entière. Par conséquent, il a accès aux variables de classe externes, y compris les variables statiques et privées :
public class Main {

   private static int currentErrorsCount = 23;

   public static void main(String[] args) {

       MonitoringSystem errorModule = new MonitoringSystem() {

           @Override
           public void startMonitoring() {
               System.out.println("Bug Tracking Monitoring Started!");
           }

           public int getCurrentErrorsCount() {

               return currentErrorsCount;
           }
       };
   }
}
Elles ont quelque chose en commun avec les classes locales : elles ne sont visibles qu'à l'intérieur de la méthode dans laquelle elles sont définies. Dans l'exemple ci-dessus, toute tentative d'accès à l'objet errorModuleen dehors de la méthode main()échouera. Et une autre limitation importante que les classes anonymes ont héritée de leurs « ancêtres » - les classes internes : une classe anonyme ne peut pas contenir de variables et de méthodes statiques . Si nous essayons de rendre la méthode getCurrentErrorsCount()de l'exemple ci-dessus statique, le compilateur générera une erreur :
//error! Inner classes cannot have static declarations
public static int getCurrentErrorsCount() {

   return currentErrorsCount;
}
On obtient le même résultat si l'on essaie de déclarer une variable statique :
MonitoringSystem errorModule = new MonitoringSystem() {

   //error! Inner classes cannot have static declarations!
   static int staticInt = 10;

   @Override
   public void startMonitoring() {
       System.out.println("Bug Tracking Monitoring Started!");
   }

};
Enfin, je peux vous recommander une excellente vidéo sur le thème des cours anonymes, où ce sujet est expliqué le plus simplement et le plus clairement possible :)
Et notre leçon d'aujourd'hui est terminée ! Et bien que nous ayons abordé le dernier groupe de classes imbriquées, nous n’en avons pas encore fini avec ce sujet. Qu’allons-nous étudier ensuite à propos des classes imbriquées ? Vous le saurez certainement bientôt ! :)
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION