J'ai eu du mal à comprendre les cours anonymes en me préparant à l'examen OCJP-Gold. Les classes anonymes sont également importantes pour comprendre les expressions lambda et les API de flux. Par conséquent, ici, je vais lire divers livres et organiser les idées qui m'ont aidé à comprendre la classe anonyme.
Tout d'abord, implémentez l'interface normalement sans utiliser la classe anonyme et vérifiez le code qui appelle la méthode.
Sample1.java
1 interface Foo {//interface
2 void methodA();//Méthode abstraite
3 }
4
5 class FooImple implements Foo {//Classe d'implémentation
6 @Override
7 public void methodA() {//Remplacement de méthode abstraite
8 System.out.println("methodA");
9 }
10 }
11
12 public class Sample1 {//Classe d'exécution
13 public static void main(String[] args) {
14
15 Foo f = new FooImple();//Générer une classe d'implémentation et l'affecter à une variable
16 f.methodA();//Appel d'une méthode sur une variable à laquelle la classe d'implémentation est affectée
17
18 new FooImple().methodA();//Pas besoin d'affecter des variables si seuls les appels de méthode
19 }
20 }
Résultat d'exécution
methodA
methodA
Dans Sample1.java
, l'interface Foo
, sa classe d'implémentation FooImple
et la classe d'exécutionSampole1
apparaîtront.
Il n'y a rien de particulièrement difficile, mais supposons que la méthode methodA ()
qui est implémentée et appelée ici est ** une méthode qui n'est pas prévue pour être réutilisée ailleurs et qui est nécessaire sur une base ad hoc **. ..
Dans un tel cas, il semble difficile de se donner la peine de définir la classe d'implémentation de l'interface Foo
et de l'utiliser. ** **
De plus, comme le processus lui-même n'est pas un gros processus, le code lui-même peut être raccourci, mais si vous souhaitez appeler de nombreuses méthodes qui implémentent des implémentations similaires, vous devez définir ** autant de classes d'implémentation que de méthodes que vous souhaitez implémenter. il y a. ** **
S'il se trouve dans le même fichier de classe, le problème semble mineur, mais s'il est divisé en différents fichiers de classe, il peut être difficile à gérer.
Une implémentation utilisant une classe anonyme peut être utilisée pour résoudre de tels problèmes. Il existe deux façons d'écrire une implémentation à l'aide d'une classe anonyme. Vérifiez chacun avec un code.
Sample2.java
1 interface Foo {//interface
2 void methodA();//Méthode abstraite
3 }
4
5 public class Sample2 {//Classe d'exécution
6 public static void main(String[] args) {
7 Foo f = new Foo() {//Affectez le résultat implémenté par la classe anonyme à la variable f
8 @Override
9 public void methodA() {//Remplacement de méthode abstraite
10 System.out.println("methodA");
11 }
12 };
13 f.methodA();//Appel d'une méthode à la classe d'implémentation
14 }
15 }
Résultat d'exécution
methodA
Dans Sample2.java
, l'interface Foo
et la classe d'exécution Sampole2
apparaîtront.
FooImple
, qui est une classe d'implémentation de l'interface Foo qui apparaissait dans Sample1.java
, n'apparaîtra pas en l'implémentant avec une classe anonyme.
** En utilisant une classe anonyme, vous pouvez «déclarer une classe» et «créer une instance» en même temps. ** **
Si vous ne pouvez pas obtenir une image simplement en regardant cet exemple, veuillez le comparer avec le Sample1.java
ci-dessus.
La 15e ligne de Sample1.java
a été remplacée par les 7e à 12e lignes de Sample2.java
.
Vous pouvez voir que le côté droit de Foo f = new FooImple ();
est new Foo ()
.
De plus, vous pouvez voir que le contenu (définition de méthode) de la classe FooImple
a été déplacé vers le suivant Foo f = new Foo ()
(lignes 8 à 10).
En faisant cela, vous pouvez définir et utiliser la classe d'implémentation dans la classe d'exécution sans avoir à définir la classe d'implémentation que vous ne prévoyez pas de réutiliser.
Notez que la 18e ligne de Sample1.java
ne peut être utilisée que si la classe FooImple
est définie, elle est donc supprimée de Sample2.java
.
Ce modèle est décrit ci-dessous.
De plus, si vous souhaitez simplement exécuter la méthode ** et que vous ne prévoyez pas de réutiliser la classe implémentée, vous n'avez même pas besoin de l'affecter à une variable. ** ** Ceci est lié à la ligne 18 de «Sample1.java» mentionnée précédemment.
Sample3.java
1 interface Foo {//interface
2 void methodA();//Méthode abstraite
3 }
4
5 public class Sample3 {//Classe d'exécution
6 public static void main(String[] args) {
7 new Foo() {//Implémentation en classe anonyme sans déclaration de variable
8 @Override
9 public void methodA() {//Remplacement de méthode abstraite
10 System.out.println("methodA");
11 }
12 }.methodA();//Appel d'une méthode à la classe d'implémentation
13 }
14 }
Si vous ne pouvez pas obtenir une image simplement en regardant cet exemple, veuillez le comparer avec le Sample2.java
ci-dessus.
C'est presque la même chose que «Sample2.java», mais les 7e et 12e lignes sont différentes.
Vous pouvez voir que le côté gauche de Foo f = new Foo ()
(7ème ligne) est manquant et que f
de f.methodA ();
(13ème ligne) est manquant. ..
En effet, l'instance créée est affectée à la variable f et l'implémentation qui a appelé methodA () pour cette variable f est temporairement utilisée sans l'affecter à la variable pour appeler methodA ().
Dans les exemples 1, 2 et 3, nous avons organisé l'implémentation de l'interface qui n'a pas d'arguments et de valeurs de retour, mais nous avons également créé un exemple de code pour ** l'implémentation d'interfaces qui ont des arguments et des valeurs de retour **, je vais donc l'ajouter. Si vous comprenez l'idée des échantillons 1, 2 et 3, il n'y a rien de particulièrement difficile, je vais donc omettre l'explication.
Sample4.java
1 interface Foo {//interface
2 String methodA(String str);//Une méthode abstraite qui prend un type String comme argument et retourne un type String
3 }
4
5 class FooImple implements Foo {//Classe d'implémentation
6 @Override
7 public String methodA(String str) {//Remplacement de méthode abstraite
8 return "Hello " + str;
9 }
10 }
11
12 public class Sample4 {//Classe d'exécution
13 public static void main(String[] args) {
14 Foo f = new FooImple();//Générez une classe d'implémentation et affectez-la à la variable f
15 String str = f.methodA("methodA");//Assignez la valeur de retour de la méthode à la variable str
16 System.out.println(str);
17 }
18 }
Résultat d'exécution
Hello methodA
Sample5.java
1 interface Foo {//interface
2 String methodA(String str);//Une méthode abstraite qui prend un type String comme argument et retourne un type String
3 }
4
5 public class Sample5 {//Classe d'exécution
6 public static void main(String[] args) {
7 Foo f = new Foo() {//Générez une classe d'implémentation et affectez-la à la variable f
8 @Override
9 public String methodA(String str) {//Remplacement de méthode abstraite
10 return "Hello " + str;
11 }
12 };
13 String str = f.methodA("methodA");//Assignez la valeur de retour de la méthode à la variable str
14 System.out.println(str);
15 }
16 }
Sample6.java
1 interface Foo {//interface
2 String methodA(String str);//Une méthode abstraite qui prend un type String comme argument et retourne un type String
3 }
4
5 public class Sample6 {//Classe d'exécution
6 public static void main(String[] args) {
7 String str = new Foo() {//Générez une classe d'implémentation mais ne l'affectez pas à une variable, mais affectez le résultat de l'exécution de la méthode à la variable str
8 @Override
9 public String methodA(String str) {//Remplacement de méthode abstraite
10 return "Hello " + str;
11 }
12 }.methodA("methodA");//Appeler une méthode sur l'instance créée
13 System.out.println(str);
14 }
15 }
J'ai organisé l'idée de classe anonyme. ** Il est important de comprendre quelle est la différence si vous n'utilisez pas de classes anonymes. ** ** Ce faisant, vous pouvez comprendre les avantages des cours anonymes, et il est également utile comme préparation aux examens. Veuillez comparer attentivement les échantillons 1, 2 et 3 pour comprendre la différence entre eux.
En outre, l'exemple de code est téléchargé ci-dessous, veuillez donc vous y référer si vous le souhaitez.
** Addendum (2019/1/31) ** Les échantillons 4, 5 et 6 ont également été ajoutés à l'exemple de code ci-dessus.
Recommended Posts