Hello,
Les références de méthodes peuvent être données là où on attend une interface fonctionnelle compatible.
En gros si on a une interface fonctionnelle MonInterface, et une classe MaClasse qui possède une méthode maMethode() compatible avec cette interface fonctionnelle, on peut faire ça :
MonInterface mi = MaClasse::maMethode;
Et donc si une méthode autreMethode() prend en paramètre un objet de type MonInterface, en gros, si elle est définie comme ça :
void autreMethode(MonInterface mi) {
alors on peut l'appeler comme ça :
autreMethode(MaClasse::maMethode);
Ok. Reste à définir ce qu'est une interface fonctionnelle. Eh bien c'est :
- une interface
- qui fournit une et seulement une méthode abstraite
Donc pour voir si une interface est une interface fonctionnelle, on compte ses méthodes abstraites.
Les champs qu'elle définit ? => ça compte pas, c'est pas des méthodes.
Les classes, interfaces, enums qu'elle définit ? => ça compte pas, c'est pas des méthodes.
Les méthodes static ? => ça compte pas, elles sont toujours définies.
Les méthodes par défaut ? => ça compte pas, elles sont définies.
Les méthode privées ? => ça compte pas, elles sont toujours définies.
Les méthodes non définies ? => voilà, on compte ça.
Et s'il y en a une et exactement une, alors l'interface est une interface fonctionnelle. À noter que si une interface étend d'autres interfaces, elle hérite des méthodes de ces interfaces, donc les non définies héritées comme ça, comptent aussi.
Bref, une interface fonctionnelle, ça ressemble à ça :
1 2 3
| interface MonInterface {
void uneMethode(); // une méthode abstraite, et une seule
} |
Pour en revenir aux méthodes File.listFiles(), voyons lesquelles prennent une interface fonctionnelle en paramètre :
- public File[] listFiles() => pas de paramètre, donc c'est pas bon.
- public File[] listFiles(FilenameFilter filter) => en regardant FilenameFilter on constate que c'est une interface fonctionnelle, donc on garde pour l'instant.
- public File[] listFiles(FileFilter filter) => en regardant FileFilter on constate que c'est une interface fonctionnelle, donc on garde pour l'instant.
Reste donc deux candidates possibles.
Ces deux-là prennent en paramètre une interface fonctionnelle, mais encore faut-il qu'elle soit compatible avec File::isHidden
Pour qu'une référence de méthode soit compatible avec une interface fonctionnelle, il faut que :
- La référence de méthode puisse recevoir les mêmes paramètres que la méthode de l'interface fonctionnelle
- La méthode de la référence de méthode renvoie un type qui peut être utilisé pour le type de retour de la méthode de l'interface fonctionnelle.
Alors, étudions la référence de méthode File::isHidden.
File.isHidden() est une méthode qui ne prend pas de paramètre.
Mais c'est une méthode d'instance, et File::isHidden est une référence qui ne précise pas d'instance, seulement la classe File.
La référence de méthode doit donc prendre en paramètre, une instance de File. Et c'est tout. Un seul paramètre.
File.isHidden() renvoie un boolean.
Maintenant regardons les interfaces fonctionnelles qui étaient proposées en paramètre de File.listFiles() :
- FilenameFilter : méthode boolean accept(File dir, String name). Deux paramètres. Notre référence de méthode n'en accepte qu'un. Ça ne colle pas.
- FileFilter : méthode boolean accept(File pathname). Un paramètre de type File. Ça colle. Type de retour boolean. Ça colle aussi.
=> Conclusion, c'est la méthode public File[] listFiles(FileFilter filter) qui était en mesure d'accepter la référence de méthode File::isHidden
Partager