Es fiel mir schwer, anonyme Klassen zu verstehen, als ich mich auf die OCJP-Gold-Prüfung vorbereitete. Anonyme Klassen sind auch wichtig, um Lambda-Ausdrücke und Stream-APIs zu verstehen. Deshalb werde ich hier verschiedene Bücher lesen und die Ideen organisieren, die mir geholfen haben, die anonyme Klasse zu verstehen.
Implementieren Sie die Schnittstelle zunächst normal, ohne die anonyme Klasse zu verwenden, und überprüfen Sie den Code, der die Methode aufruft.
Sample1.java
1 interface Foo {//Schnittstelle
2 void methodA();//Abstrakte Methode
3 }
4
5 class FooImple implements Foo {//Implementierungsklasse
6 @Override
7 public void methodA() {//Abstrakte Methode überschreiben
8 System.out.println("methodA");
9 }
10 }
11
12 public class Sample1 {//Ausführungsklasse
13 public static void main(String[] args) {
14
15 Foo f = new FooImple();//Generieren Sie eine Implementierungsklasse und weisen Sie sie einer Variablen zu
16 f.methodA();//Aufruf einer Methode für die Variable, der die Implementierungsklasse zugewiesen ist
17
18 new FooImple().methodA();//Keine Notwendigkeit, Variablen zuzuweisen, wenn nur Methodenaufrufe
19 }
20 }
Ausführungsergebnis
methodA
methodA
In Sample1.java
erscheinen die Schnittstelle Foo
, ihre Implementierungsklasse FooImple
und die AusführungsklasseSampole1
.
Es gibt nichts besonders Schwieriges, aber nehmen wir an, dass die hier implementierte und aufgerufene Methode methodA ()
** eine Methode ist, die nicht anderweitig wiederverwendet werden soll und ad hoc benötigt wird **. ..
In einem solchen Fall scheint es schwierig zu sein, die Implementierungsklasse der Foo-Schnittstelle zu definieren und zu verwenden. ** ** **
Da der Prozess selbst kein großer Prozess ist, kann der Code selbst gekürzt werden. Wenn Sie jedoch viele Methoden aufrufen möchten, die ähnliche Implementierungen implementieren, müssen Sie ** so viele Implementierungsklassen definieren, wie es Methoden gibt, die Sie implementieren möchten. es gibt. ** ** **
Wenn sich dies in derselben Klassendatei befindet, scheint das Problem gering zu sein. Wenn es jedoch in verschiedene Klassendateien unterteilt ist, kann die Verwaltung schwierig sein.
Eine Implementierung mit einer anonymen Klasse kann verwendet werden, um solche Probleme zu lösen. Es gibt zwei Möglichkeiten, eine Implementierung mit einer anonymen Klasse zu schreiben. Überprüfen Sie jeweils mit einem Code.
Sample2.java
1 interface Foo {//Schnittstelle
2 void methodA();//Abstrakte Methode
3 }
4
5 public class Sample2 {//Ausführungsklasse
6 public static void main(String[] args) {
7 Foo f = new Foo() {//Ordnen Sie das von der anonymen Klasse implementierte Ergebnis der Variablen f zu
8 @Override
9 public void methodA() {//Abstrakte Methode überschreiben
10 System.out.println("methodA");
11 }
12 };
13 f.methodA();//Aufruf einer Methode an die Implementierungsklasse
14 }
15 }
Ausführungsergebnis
methodA
In Sample2.java
erscheinen die Schnittstelle Foo
und die Ausführungsklasse Sampole2
.
FooImple
, eine Implementierungsklasse der Foo-Schnittstelle, die in Sample1.java
angezeigt wurde, wird nicht angezeigt, wenn sie mit einer anonymen Klasse implementiert wird.
** Durch die Verwendung einer anonymen Klasse können Sie gleichzeitig "eine Klasse deklarieren" und "eine Instanz erstellen". ** ** **
Wenn Sie durch Betrachten dieses Beispiels kein Bild erhalten können, vergleichen Sie es bitte mit dem obigen Sample1.java
.
Die 15. Zeile von "Sample1.java" wurde durch die 7. bis 12. Zeile von "Sample2.java" ersetzt.
Sie können sehen, dass die rechte Seite von Foo f = new FooImple ();
new Foo ()
ist.
Sie können auch sehen, dass der Inhalt (Methodendefinition) der Klasse "FooImple" in das folgende "Foo f = new Foo ()" verschoben wurde (Zeilen 8 bis 10).
Auf diese Weise können Sie die Implementierungsklasse in der Ausführungsklasse definieren und verwenden, ohne die Implementierungsklasse definieren zu müssen, die Sie nicht wiederverwenden möchten.
Beachten Sie, dass die 18. Zeile von "Sample1.java" nur verwendet werden kann, wenn die "FooImple" -Klasse definiert ist. Daher wird sie aus "Sample2.java" gelöscht.
Dieses Muster wird unten beschrieben.
Wenn Sie nur die ** -Methode ausführen möchten und die implementierte Klasse nicht wiederverwenden möchten, müssen Sie sie nicht einmal einer Variablen zuweisen. ** ** **
Dies bezieht sich auf die zuvor erwähnte Zeile 18 von Sample1.java
.
Sample3.java
1 interface Foo {//Schnittstelle
2 void methodA();//Abstrakte Methode
3 }
4
5 public class Sample3 {//Ausführungsklasse
6 public static void main(String[] args) {
7 new Foo() {//Implementierung in anonymer Klasse ohne Variablendeklaration
8 @Override
9 public void methodA() {//Abstrakte Methode überschreiben
10 System.out.println("methodA");
11 }
12 }.methodA();//Aufruf einer Methode an die Implementierungsklasse
13 }
14 }
Wenn Sie durch Betrachten dieses Beispiels kein Bild erhalten können, vergleichen Sie es bitte mit dem obigen Sample2.java
.
Es ist fast dasselbe wie Sample2.java
, aber die 7. und 12. Zeile sind unterschiedlich.
Sie können sehen, dass die linke Seite von Foo f = new Foo ()
(7. Zeile) fehlt und dass f
von f.methodA ();
(13. Zeile) fehlt. ..
Dies liegt daran, dass die erstellte Instanz der Variablen f zugewiesen ist und die Implementierung, die methodA () für diese Variable f aufgerufen hat, vorübergehend verwendet wird, ohne sie der Variablen zum Aufrufen von methodA () zuzuweisen.
In den Beispielen 1, 2 und 3 haben wir die Implementierung der Schnittstelle ohne Argumente und Rückgabewerte organisiert, aber wir haben auch Beispielcode für ** die Implementierung von Schnittstellen mit Argumenten und Rückgabewerten ** erstellt, daher werde ich ihn hinzufügen. Wenn Sie die Idee in den Beispielen 1, 2 und 3 verstehen, gibt es nichts besonders Schwieriges, daher werde ich die Erklärung weglassen.
Sample4.java
1 interface Foo {//Schnittstelle
2 String methodA(String str);//Eine abstrakte Methode, die einen String-Typ als Argument verwendet und einen String-Typ zurückgibt
3 }
4
5 class FooImple implements Foo {//Implementierungsklasse
6 @Override
7 public String methodA(String str) {//Abstrakte Methode überschreiben
8 return "Hello " + str;
9 }
10 }
11
12 public class Sample4 {//Ausführungsklasse
13 public static void main(String[] args) {
14 Foo f = new FooImple();//Generieren Sie eine Implementierungsklasse und weisen Sie sie der Variablen f zu
15 String str = f.methodA("methodA");//Weisen Sie der Variablen str den Rückgabewert der Methode zu
16 System.out.println(str);
17 }
18 }
Ausführungsergebnis
Hello methodA
Sample5.java
1 interface Foo {//Schnittstelle
2 String methodA(String str);//Eine abstrakte Methode, die einen String-Typ als Argument verwendet und einen String-Typ zurückgibt
3 }
4
5 public class Sample5 {//Ausführungsklasse
6 public static void main(String[] args) {
7 Foo f = new Foo() {//Generieren Sie eine Implementierungsklasse und weisen Sie sie der Variablen f zu
8 @Override
9 public String methodA(String str) {//Abstrakte Methode überschreiben
10 return "Hello " + str;
11 }
12 };
13 String str = f.methodA("methodA");//Weisen Sie der Variablen str den Rückgabewert der Methode zu
14 System.out.println(str);
15 }
16 }
Sample6.java
1 interface Foo {//Schnittstelle
2 String methodA(String str);//Eine abstrakte Methode, die einen String-Typ als Argument verwendet und einen String-Typ zurückgibt
3 }
4
5 public class Sample6 {//Ausführungsklasse
6 public static void main(String[] args) {
7 String str = new Foo() {//Generieren Sie eine Implementierungsklasse, weisen Sie sie jedoch keiner Variablen zu, sondern weisen Sie der Variablen str das Ergebnis der Methodenausführung zu
8 @Override
9 public String methodA(String str) {//Abstrakte Methode überschreiben
10 return "Hello " + str;
11 }
12 }.methodA("methodA");//Rufen Sie eine Methode für die erstellte Instanz auf
13 System.out.println(str);
14 }
15 }
Ich habe die Idee des anonymen Unterrichts organisiert. ** Es ist wichtig zu verstehen, was der Unterschied ist, wenn Sie keine anonymen Klassen verwenden. ** ** ** Auf diese Weise können Sie die Vorteile anonymer Klassen verstehen und es ist auch nützlich, um sich auf Prüfungen vorzubereiten. Bitte vergleichen Sie die Proben 1, 2 und 3 sorgfältig, um den Unterschied zwischen ihnen zu verstehen.
Außerdem wird der Beispielcode unten hochgeladen. Wenn Sie möchten, lesen Sie ihn bitte.
** Nachtrag (31.01.2019) ** Die Proben 4, 5 und 6 wurden ebenfalls zum obigen Beispielcode hinzugefügt.
Recommended Posts