|
Publicité ' | ||||||||||||||||||||||||
|
|
#21 |
|
Membre chevronné
![]() ![]() |
adiGuba
|
|
00
|
|
|
#22 | ||||||
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
Je viens de découvrir autre chose concernant les interfaces.
Pour rappel il y a les "default methods" qui permettront d'intégrer du code dans les interfaces : Code :
La méthode method2() est optionnelle et utilisera le code par défaut si elle n'est pas implémenté par la classe. Mais ce n'est pas tout, on pourra utiliser des méthodes private, destiné à être utiliser dans les "default methods" afin de pouvoir mutualiser le code. Par exemple : Code :
Enfin les interfaces pourront contenir des méthodes static : Code :
Attention toutefois car à l'heure actuelle ceci n'est implémenté que dans le compilateur. En clair cela va compiler normalement, mais cela risque de générer des erreurs à l'exécution... Sources : Enhancement: Add support for static interface methods Enhancement: Add experimental support for private (instance) interface methods a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
||||||
|
20
|
|
|
#23 |
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
C'est le principe des "default's methods" qui permet de définir une implémentation par défaut dans une interface. Les classes qui l'implémente n'auront pas l'obligation d'implémenter la méthode.
Cette notion a eu plusieurs noms, et j'en ai pas mal parlé sur mon blog :
Cela n'a pas de sens. Les méthodes static d'une interface ne sont pas hérité ni rien. Elle doivent impérativement être appelé via la syntaxe NomDeLinterface.method(). a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
|
00
|
|
|
#24 |
|
Membre éclairé
![]() Développeur informatique Inscription : décembre 2011 Messages : 237 ![]() |
Bonjour,
abiGuba, quels seront les différences entre ces interfaces et une classe abstraite ? Est-ce que c'est semblable aux Traits et Mixins ? Comment résoudre le problème d'héritage multiple si une classe implémente 2 interfaces qui contiennent une méthode defaut avec le même nom mais un contenu différent ? |
|
|
00
|
|
|
#25 | |
|
Membre éclairé
![]() |
Citation:
|
|
|
00
|
|
|
#26 |
|
Membre éclairé
![]() Développeur informatique Inscription : décembre 2011 Messages : 237 ![]() |
Ça parait logique de ce point de vue, mais alors pourquoi la compilation est autorisée en C++ ? ...
Aussi quel différence y a-t-il maintenant entre une interface et une classe abstraite ? Pour moi une interface était une classe 100% abstraite, je vais devoir changer ma définition de la chose. |
|
|
00
|
|
|
#27 | |||||
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
Citation:
Oui cela s'en approche beaucoup. Citation:
On peut bien sûr se contenter de réutiliser une implémentation d'une interface via une syntaxe spécifique, par exemple : Code :
Par contre les règles sont plus souples, car si la méthode est implémenter dans une classe parente, cela prendra toujours la priorité sur les méthodes par défaut, qui comme leur nom l'indique, ne seront utilisé QUE dans le cas où la classe ne possèdent pas d'implémentation. Là où cela est très intéressant, c'est que la résolution de la méthode est géré par la JVM au runtime. C'est à dire que cela permet d'ajouter une méthode à une interface sans avoir à recompiler toutes les classes qui l'implémentent... Citation:
En Java toutes les méthodes sont implicitement virtuelles et donc hérités par défaut, alors que c'est exactement l'inverse en C++. Du coup les problèmes que l'on peut rencontrer via l'héritage multiple sont moins visible... a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
|||||
|
30
|
|
|
#28 | |||
|
Membre chevronné
![]() ![]() |
Citation:
Je donne un code exemple: Code :
|
|||
|
00
|
|
|
#29 | ||||||||
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
@la.lune
Réponse courte : oui ton code fonctionne Réponse longue : Une interface fonctionnelle c'est juste une interface qui ne contient qu'une seule et unique méthode abstraite (sans compter les "default's methods" donc), comme par exemple Runnable. Les lambdas et les références de méthode ne peuvent être convertis qu'en une interface fonctionnelle, à condition que leurs signatures correspondent. Par exemple dans ce cas là la méthode Iterable::forEach() est définie comme ceci : Code :
Grosso-modo elle est définie comme ceci : Code :
Si tu références une méthode static, alors la signature de cette méthode devra correspondre à la signature de l'interface. C'est le cas dans ton exemple donc cela marchera bien Après tu as encore le cas particulier des méthodes d'instances, où tu as deux possibilités :
Exemple Object::toString pourra être associer avec une interface fonctionnelle tel quel celle-ci : Code :
A l'inverse pour une instance d'objet "o", o::toString sera associable avec une interface fonctionnelle comme ceci : Code :
Je ne sais pas si tout est bien clair... a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
||||||||
|
10
|
|
|
#30 |
|
Membre chevronné
![]() ![]() |
Oui j'ai compris en grog, même si j'avais fait juste fait une erreur en oubliant le mot "void" pour methode(..).
Mais là encore juste pour plus de précision, je me demande quelle est l'interface référencé ici quand tu dis "Si tu références une méthode static, alors la signature de cette méthode devra correspondre à la signature de l'interface", En quelle interface fonctionnelle la lamba sera converti?(l'interface dont sa signature correspond à celle de ma méthode static) Je n'ai pas bien saisi, où est la correspondance exactement? Aussi, je suis je suis un peu perdu quand tu parles de correspondance entre signature de méthode et signature d'interface, ou bien tu veux parler de correspondance entre signature de méthode et signature de la méthode de l'interface fonctionnelle. L'exemple que tu as donné c'est sur une interface fonctionnelle déjà existante, est ce le cas pour les autres? Ce que je n'arrive pas à saisir. Sur tes premières réponses tu parles de méthodes générés dynamiquement, donc si je ne me trompe pas, est-ce ma référence de méthode sera converti dynamiquement en interface fonctionnelle lors de la compilation? |
|
00
|
|
|
#31 | |||||||||||
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
Citation:
Une lambda (ou une référence de méthode) ne peut être associé qu'à une interface fonctionnelle, et il faut que la signature correspondent à celle de la méthode : Par exemple : Code :
ActionListener listener = (ActionEvent e) -> System.out.println("ActionEvent = " + e); Code :
public void actionPerformed(ActionEvent e); Code :
ActionListener listener = (e) -> System.out.println("ActionEvent = " + e); Et c'est la même chose pour les références de méthode. Si on a une méthode définie comme ceci : Code :
Code :
ActionListener listener = MaClasse::onEvent;
S'il s'agit d'une méthode d'instance : Code :
Code :
ActionListener listener = MaClasse::doSomething; // ERREUR Code :
Et pour les méthodes c'est la même chose. Les méthodes qui utiliseront les lambdas n'ont rien de spécial, si ce n'est qu'elles utilisent une interface fonctionnelle. Mais même si cette notion est "nouvelle", cela ne l'est pas vraiment car l'API standard est déjà pleine d'interface fonctionnelle... Du coup on pourra utiliser les lambdas/références de méthode avec des APIs existante, du moment qu'elles utilisent une interface fonctionnelle : Code :
C'est le "Type inference" qui se chargera de vérifier le tout, c'est à dire :
Et en cas de surcharge, le compilo ira chercher la version de la méthode qui correspond. A noter également l'existence de référence de constructeur (en utilisant ::new), par exemple : Code :
a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
|||||||||||
|
10
|
|
|
#32 | ||||||
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
Autre petite subtilité que j'ai découverte aujourd'hui : de nombreuses interfaces fonctionnelles (déjà existante ou non) sont enrichies de "default's method" permettant diverses choses.
Par exemple pour trier une liste d'User par nom, on pourra utiliser le code suivant : Code :
Or l'interface Comparator est doté de nouvelle méthode permettant de créer des dérivés. Par exemple on peut inverser l'ordre de tri très simplement : Code :
Par exemple pour tirer par nom, prénom puis date de naissance on pourra faire ceci : Code :
a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
||||||
|
10
|
|
|
#33 |
|
Membre chevronné
![]() ![]() |
pour l'éclaircissement et merci encore de nous faire part de ces nouveautés . Pour ma question là j'ai bien compris, surtout là je vois que si tu m'avait juste répondu en précisant que la signature de ma méthode satic void methode(A) correspond exactement à la signature de la méthode de l'interface fonctionnelle qu'attend un foreach qui est void(T) j'aurais tout compris et surpasser toutes les ambiguïtés. De plus j'ai une autre question sur la parallélisation dont tu as mentionné sur les multiples instruction dont on applique à une collection, alors quand tu dis 'si cela est possible', je me pose la question possible dans le sens où certaines instructions dépendent des précédentes ou dans le sens de la capacité de l'ordinateur de paralléliser, et là aussi il y a deux option soit de la parallélisation juste en différents thread qui serait optimisée avec les architectures multi-core ou bien de la vrai parallélisation. Ma dernière question c'est que tu parles d'interfaces de types qui ne sont pas encore finalisés dans une de tes réponses, alors peux-tu nous donner plus de détailles sur l'objet de ces interfaces et leur domaines d'applications. |
|
00
|
|
|
#34 | |||||||||||
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
Citation:
Citation:
Par exemple si tu veux stocker le résultat dans une collection, il faut que cette dernière soit thread-safe, car si ce n'est pas le cas cela engendrera des erreurs. Du coup même si tu choisis un stream parallel ce type d'opération sera en séquentiel par défaut (en fait c'est l'implémentation de la collection qui peut modifier cela). Citation:
Quelques exemples : Block<T> qui permet d'exécuter un bout de code en prenant un objet en paramètre (c'est ce qui est utiliser par forEach() par exemple) : Code :
Code :
Code :
Code :
On y retrouve aussi des versions optimisés pour les types primitifs, ou des versions "Bi" prenant deux paramètres (et utilisé par les Map pour les clef/valeur). Il n'y a rien d'exceptionnel là dedans, c'est juste pour fournir une base commune qui sera utilisable par tout le monde plutôt que de réécrire tout plein d'interface similaire dans chaque API a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
|||||||||||
|
10
|
|
|
#35 |
|
Membre chevronné
![]() ![]() |
pour ces réponses.Là tu vient de m'éclairer sur ces fonctions. Merci aussi pour le lien, je vois bien les détailles sur ces fonctions. Vraiment j'ai hâte de voir la sortie de la JVM 1.8 pour commencer à coder nos programmes avec ces fonctionnalités très intéressantes, on aura à écrire peu de code, et surtout nous le fan de javafx on aura à tout simplifier lors de la sortie de Javafx 8 avec le JSE8 ( déjà la date est-elle officialisée pour quand?) . Là si j'ai bien compris à présent le boulot c'est de maîtriser aussi ces interfaces à utiliser pour écrire de bon expressions lambda(ou référence de méthode) et les autres interfaces. On va bien voir la grande utilité dans des milliers de lignes de codes qui seront réduits disons jusqu’à 40% (possible). De plus ceci permettra aussi de bien structurer l'architecture du programme, on crée les interfaces( et leur implémentation si on) à part et fait les traitement à part en faisant référence aux méthodes. En tout cas c'est une évolution marquante du langage. |
|
00
|
|
|
#36 | ||||
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
Il y a un nouveau build du JDK8/Lambda : http://jdk8.java.net/lambda/
Je n'ai pas vraiment eu le temps de le parcourir, mais l'interface Map s'est enrichie de plusieurs méthodes par défaut, en plus du forEach() dont j'avais déjà parlé ! Rien d'extraordinaire en soit, mais quand même des méthodes bien utile : Code :
A noter que ce "computeIfAbsent()" nous permettra d'implémenter une MultiMap en un rien de temps : Code :
a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
||||
|
10
|
|
|
#37 | ||||||
|
Membre éclairé
![]() Développeur informatique Inscription : décembre 2011 Messages : 237 ![]() |
Bonjour,
Je lu l'article sur la syntaxe des lambdas (écrit par adiGuba). 1. J'aurais aimé savoir s'il y avait une différence entre le fait de préciser le type d'un argument ou non : Code :
2. Aussi, si on utilise un lambda dans une classe, pourra-t-on automatiquement avoir accès au this dans le lambda (sans avoir à le faire passer par un paramètre) ? En C++11 ou PHP5.3 il est possible de faire passer des variables externes au bloc lambda, on fait alors la distinction entre fonction anonyme et fermeture du lambda. En C++11 par exemple : Code :
Code :
Merci |
||||||
|
|
00
|
|
|
#38 | |||||
|
Expert Confirmé Sénior
![]() ![]() Développeur Java/Web Inscription : avril 2002 Messages : 12 654 ![]() |
Citation:
Citation:
Citation:
Code :
C'est à dire que la variable doit être définie et ne doit pas être modifié dans la lambda ou en dehors... a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java |
|||||
|
20
|
|
|
#39 |
|
Membre éclairé
![]() Développeur informatique Inscription : décembre 2011 Messages : 237 ![]() |
Merci beaucoup adiGuba
|
|
|
00
|
Copyright © 2000-2013 - www.developpez.com