JavaRush /Java-Blog /Random-DE /Anonyme Klassen in Java

Anonyme Klassen in Java

Veröffentlicht in der Gruppe Random-DE
Hallo! In der heutigen Lektion beschäftigen wir uns weiterhin mit dem Thema verschachtelter Klassen. Die letzte Gruppe ist an der Reihe – anonyme innere Klassen in Java. Kehren wir zu unserem Diagramm zurück: Anonymer Unterricht - 2Wie die lokalen Klassen, über die wir in der letzten Vorlesung gesprochen haben, sind anonyme Klassen eine Teilmenge innerer Klassen. Sie weisen auch einige Gemeinsamkeiten und Unterschiede auf. Aber zuerst wollen wir es herausfinden: Warum werden sie eigentlich „anonym“ genannt? Schauen wir uns dazu ein einfaches Beispiel an. Stellen Sie sich vor, wir hätten ein Hauptprogramm, das ständig läuft und etwas tut. Wir wollen für dieses Programm ein Monitoringsystem bestehend aus mehreren Modulen erstellen. Ein Modul überwacht allgemeine Leistungsindikatoren und führt ein Protokoll, das zweite erfasst und protokolliert Fehler im Fehlerprotokoll, das dritte überwacht verdächtige Aktivitäten: zum Beispiel unbefugte Zugriffsversuche und andere sicherheitsrelevante Dinge. Da alle drei Module grundsätzlich direkt am Programmanfang starten und im Hintergrund laufen sollen, bietet es sich an, eine gemeinsame Schnittstelle für sie zu erstellen:
public interface MonitoringSystem {

   public void startMonitoring();
}
Es wird von 3 spezifischen Klassen implementiert:
public class GeneralIndicatorsMonitoringModule implements MonitoringSystem {

@Override
   public void startMonitoring() {
       System.out.println(„Die Überwachung allgemeiner Indikatoren hat begonnen!“);
   }
}


public class ErrorMonitoringModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println(„Bug-Tracking-Überwachung gestartet!“);
   }
}


public class SecurityModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println(„Sicherheitsüberwachung gestartet!“);
   }
}
Es scheint, dass alles in Ordnung ist. Wir haben ein ziemlich klares System aus mehreren Modulen. Jeder von ihnen hat sein eigenes Verhalten. Wenn wir neue Module benötigen, können wir diese hinzufügen, da wir über eine Schnittstelle verfügen, die recht einfach zu implementieren ist. Aber denken wir darüber nach, wie unser Überwachungssystem funktionieren wird. Anonymer Unterricht - 3Im Wesentlichen sollten wir einfach drei Objekte erstellen – GeneralIndicatorsMonitoringModule, ErrorMonitoringModule, SecurityModule– und startMonitoring()für jedes davon eine Methode aufrufen. Das heißt, Sie müssen lediglich drei Objekte erstellen und eine Methode dafür aufrufen.
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();
   }
}
Konsolenausgabe:

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
Und für eine so kleine Aufgabe haben wir ein ganzes System geschrieben: 3 Klassen und eine Schnittstelle! Und das alles wegen 6 Codezeilen. Was sind andererseits unsere Optionen? Ja, es ist nicht sehr cool, dass wir solche „Einweg“-Klassen geschrieben haben. Aber wie können wir das beheben? Hier kommen uns anonyme innere Klassen zu Hilfe ! So sehen sie in unserem Fall aus:
public class Main {

   public static void main(String[] args) {

       MonitoringSystem generalModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println(„Die Überwachung allgemeiner Indikatoren hat begonnen!“);
           }
       };



           MonitoringSystem errorModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println(„Bug-Tracking-Überwachung gestartet!“);
           }
       };

       MonitoringSystem securityModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println(„Sicherheitsüberwachung gestartet!“);
           }
       };

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
Lasst uns herausfinden, was hier vor sich geht! Es sieht so aus, als würden wir ein Schnittstellenobjekt erstellen:
MonitoringSystem generalModule = new MonitoringSystem() {

@Override
   public void startMonitoring() {
       System.out.println(„Die Überwachung allgemeiner Indikatoren hat begonnen!“);
   }
};
Aber wir wissen schon lange, dass es unmöglich ist, Schnittstellenobjekte zu erstellen! Das stimmt, es ist unmöglich. Tatsächlich tun wir das nicht. Der Moment, in dem wir schreiben:
MonitoringSystem generalModule = new MonitoringSystem() {

};
Innerhalb der Java-Maschine geschieht Folgendes:
  1. Es wird eine unbenannte Java-Klasse erstellt, die das implementiert MonitoringSystem.
  2. Wenn der Compiler eine solche Klasse sieht, müssen Sie alle Schnittstellenmethoden implementieren MonitoringSystem(wir haben dies dreimal durchgeführt).
  3. Ein Objekt dieser Klasse wird erstellt. Achten Sie auf den Code:
MonitoringSystem generalModule = new MonitoringSystem() {

};
Am Ende steht ein Semikolon! Sie steht aus einem bestimmten Grund dort. Wir deklarieren gleichzeitig eine Klasse (über geschweifte Klammern) und erstellen ihr Objekt mit. (); Jedes unserer drei Objekte hat eine Methode startMonitoring()auf seine eigene Weise überschrieben. Am Ende rufen wir einfach diese Methode für jeden von ihnen auf:
generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
Konsolenausgabe:

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
Das ist alles! Wir haben unsere Aufgabe erledigt: Wir haben drei Objekte erstellt MonitoringSystem, sie auf drei verschiedene Arten neu definiert und dreimal aufgerufen. Alle drei Module wurden erfolgreich gestartet und funktionieren. Gleichzeitig ist der Aufbau unseres Programms deutlich einfacher geworden! GeneralIndicatorsMonitoringModuleSchließlich können Klassen ErrorMonitoringModulejetzt SecurityModuleganz aus dem Programm entfernt werden! Wir brauchen sie einfach nicht – auch ohne kommen wir gut zurecht. Wenn jede unserer anonymen Modulklassen ein anderes Verhalten oder eigene spezifische Methoden benötigt, die die anderen nicht haben, können wir sie einfach hinzufügen:
MonitoringSystem generalModule = new MonitoringSystem() {

   @Override
   public void startMonitoring() {
       System.out.println(„Die Überwachung allgemeiner Indikatoren hat begonnen!“);
   }

   public void someSpecificMethod() {

       System.out.println(„Spezifische Methode nur für das erste Modul“);
   }
};
In der Oracle-Dokumentation gibt es eine gute Empfehlung : „Verwenden Sie anonyme Klassen, wenn Sie eine lokale Klasse für den einmaligen Gebrauch benötigen.“ Eine anonyme Klasse ist eine vollwertige innere Klasse. Daher hat es Zugriff auf äußere Klassenvariablen, einschließlich statischer und privater Variablen:
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-Überwachung gestartet!“);
           }

           public int getCurrentErrorsCount() {

               return currentErrorsCount;
           }
       };
   }
}
Sie haben etwas mit lokalen Klassen gemeinsam: Sie sind nur innerhalb der Methode sichtbar, in der sie definiert sind. Im obigen Beispiel schlägt jeder Versuch fehl errorModule, außerhalb der Methode auf das Objekt zuzugreifen . main()Und noch eine wichtige Einschränkung, die anonyme Klassen von ihren „Vorfahren“ – inneren Klassen – geerbt haben: Eine anonyme Klasse kann keine statischen Variablen und Methoden enthalten . Wenn wir versuchen, die Methode aus dem obigen Beispiel statisch zu machen getCurrentErrorsCount(), gibt der Compiler einen Fehler aus:
//Fehler! Innere Klassen können keine statischen Deklarationen haben
public static int getCurrentErrorsCount() {

   return currentErrorsCount;
}
Das gleiche Ergebnis erhalten wir, wenn wir versuchen, eine statische Variable zu deklarieren:
MonitoringSystem errorModule = new MonitoringSystem() {

   //Fehler! Innere Klassen können keine statischen Deklarationen haben!
   static int staticInt = 10;

   @Override
   public void startMonitoring() {
       System.out.println(„Bug-Tracking-Überwachung gestartet!“);
   }

};
Abschließend kann ich Ihnen ein hervorragendes Video zum Thema anonymer Unterricht empfehlen, in dem dieses Thema möglichst einfach und anschaulich erklärt wird :)
Und unsere heutige Lektion ist zu Ende! Und obwohl wir die letzte Gruppe verschachtelter Klassen behandelt haben, sind wir mit diesem Thema noch nicht fertig. Was werden wir als nächstes über verschachtelte Klassen lernen? Du wirst es bestimmt bald erfahren! :) :)
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION