IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Java 8 est disponible, la plate-forme se met aux expressions lambdas


Sujet :

Java

  1. #21
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par la.lune Voir le message
    Ce que vous dites là n'est pas vrai, on ajoute rien au type, comme déjà dit on fait juste des appel static sur l'objet. Les méthodes d’extensions le contexte est purement static, pas d'encapsulation et aucun accès aux membres privés ou protégé contrairement aux méthodes par défaut de java.
    Tu connais certainement Java beaucoup mieux que moi, mais c'est pas toi qui vas m'apprendre C#

    Je sais bien que les méthodes d'extension ne sont pas réellement ajoutées au type ; mais le fait qu'elles s'utilisent comme si c'étaient des méthodes d'instance permet de faire quasiment comme si c'était vraiment le cas. Le fait qu'elles apparaissent dans l'autocomplétion les rend aussi facilement découvrables : tout d'un coup tu as plein de nouvelles méthodes sur les types qui implémentent IEnumerable<T> (par exemple).

    Après bien sûr c'est juste du sucre syntaxique pour appeler des méthodes statique, mais ça rend le code vraiment plus clair, notamment parce que ça permet le chainage ; par exemple on peut écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IEnumerable<string> namesOfChildren = people.Where(p => p.Age < 18)
                                                .Select(p => p.Name);
    Ce qui est quand même nettement plus lisible que l'équivalent écrit avec des appels de méthodes statiques "normaux" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    IEnumerable<string> namesOfChildren =
        Enumerable.Select(
            Enumerable.Where(
                people,
                p => p.Age < 18),
            p => p.Name);
    Après c'est sûr que c'est moins puissant que les defender methods de Java, dans la mesure où ça ne supporte pas le polymorphisme (puisque c'est statique, comme tu l'as souligné). Mais ça a l'avantage que tu peux "étendre" des types existants dont tu ne contrôles pas le code source, alors que tu ne peux ajouter une defender method qu'à une interface que tu contrôles.

    Pour ce qui est de l'accès aux membres privés ou protégés, les implémentations qui substituent la defender method peuvent le faire bien sûr, mais pas l'implémentation par défaut définie dans l'interface... Du coup, une defender method qui n'est pas substituée est fonctionnellement équivalente à une méthode d'extension ; c'est la possibilité de substitution qui fait finalement toute la différence.

  2. #22
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    @tomlev : A la rigueur tu peux dire que c'est syntaxiquement équivalent, mais ce n'est pas fonctionnellement équivalent.


    a++

  3. #23
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Juste pour préciser : je ne suis pas un "expert".
    C'est juste le titre donné par le forum car j'y ai beaucoup participé (à un époque), mais cela s'arrête là !
    Ce n'est pas le le titre de Develoopez.com qui m’intéresse, il y a plusieurs personnes ici, qui ont le même titre, mais cela ne veut pas vraiment dire qu'ils le sont.

    Moi je me base sur tes interventions, qui prouvent quelqu'un qui a vraiment une expertise sur la technologie Java. Des messages plus instructifs. Et le faite aussi que vous soyez sur java depuis aussi long temps, voila devant mois touts ces raisons ! Alors sauf votre modestie, mais vous êtes expert que vous le voulez ou pas.
    Citation Envoyé par adiGuba Voir le message
    Cela va même plus loin car chaque implémentation spécifique (ArrayList, LinkedList, TreeSet, HashSet, etc.) redéfini également la méthode spliterator() pour fournir une version encore mieux adapté...
    Oui je comprend mais moi je parlais de mon bon vieux implémentation de ArrayList, si Java 8 propose une amélioration, ça ne veut pas dire que je ne pas utilisé stream() sur une implémentation possible faite même en TP un jour à la Fac de en héritant de l'interface List.

    Je peux la faire bénéficier de Stream, en se contentant des implémentations par défaut, même si l’implémentation par défaut de la méthode spliterator(), List est un peu moche, en tout cas ça nous permet de ne pas tout casser, sinon ça risque . Alors j'ai bien précisé que sur mes bon vieux implémentations
    Citation Envoyé par adiGuba Voir le message
    Map n'héritent pas de Collection
    Merci de m'avoir rappeler. Désolé car j'ai tout mélangé là . C'est vrai qu'il n'hérite pas. En réalité c'est juste une faute, car j'ai fermé les yeux et quand j'étais entrain de regarder le code source de Collection j'avais vu, ça:

    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     /* @param <E> the type of elements in this collection
     * @see     Set
     * @see     List
     * @see     Map
     * @see     SortedSet
     * @see     SortedMap
     * @see     HashSet
     * @see     TreeSet
     * @see     ArrayList
     * @see     LinkedList
     * @see     Vector
     * @see     Collections
     * @see     Arrays
     * @see     AbstractCollection
     * @since 1.2
     */
     
     
    public interface Collection<E> extends Iterable<E> {
    Certes ce sont tous des conteneurs. Mais en regardant ce code là Map et StoredMap à côté des filles de Collection. Je suis tombé dans l'erreur sans me rendre compte. Alors que normalement il y a Vector, Arrays et Collections qui ne sont pas aussi des collection, mais je n'ai pas fait attention qu'ils étaient dans la liste.

    Je me suis mis à chercher spliterator() dans Map et StoredMap Avec dans la tête comme il y a quelque chose comme ça: Map <E> extends Collection<E>, alors que dans la réalité ce n'est pas le cas. Merci en tout cas du rappe.
    Citation Envoyé par adiGuba Voir le message
    Du coup ArrayList redéfinie cette méthode removeIf() afin de marquer les éléments à supprimer, et de n'effectuer le décalage qu'une seule et unique fois même si on supprime plusieurs éléments...
    Rien à dire.

  4. #24
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 15
    Points : 26
    Points
    26
    Par défaut
    J'ai quand même l'impression que les méthodes par défaut des interfaces ne sont jamais qu'un changement de nom des classes abstraites.

  5. #25
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par euskadi_21 Voir le message
    J'ai quand même l'impression que les méthodes par défaut des interfaces ne sont jamais qu'un changement de nom des classes abstraites.
    Sauf que tu peux implémenter plusieurs interfaces, alors que tu ne peux hériter que d'une seule classe...

  6. #26
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Sauf que tu peux implémenter plusieurs interfaces, alors que tu ne peux hériter que d'une seule classe...
    +1
    Sans oublier que les classes abstraites peuvent avoir un état via leurs attributs, alors que les méthodes par défaut ne peuvent que se baser sur le contrat de l'interface.


    Bref les interfaces continueront toujours de définir un contrat.
    Les méthodes par défaut pourront proposer des implémentations partielles basé sur ce contrat.

    Les classes (abstraites ou pas) permettent toujours de définir une implémentation concrète, en gérant un état via les attributs...




    Maintenant c'est sûr que les méthodes par défaut pourront remplacer avantageusement certains classes abstraites qui ne géraient pas d'état (je pense pas exemple à AbstractCollection).




    L'autre force des méthodes par défaut, c'est surtout de pouvoir faire évoluer les interfaces existantes !
    L'interface Map gagne une bonne dizaine de méthode

    a++

  7. #27
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Pour ce qui est de l'accès aux membres privés ou protégés, les implémentations qui substituent la defender method peuvent le faire bien sûr, mais pas l'implémentation par défaut définie dans l'interface... Du coup, une defender method qui n'est pas substituée est fonctionnellement équivalente à une méthode d'extension ; c'est la possibilité de substitution qui fait finalement toute la différence.
    Je ne suis pas du tout d'accord sur le fait que c'est juste la question de la substitution qui fait la différence, il y a une très grande différence aussi qui se manifeste rien qu'avec cet ajoute d’implémentation par défaut à l'interface, beaucoup de choses qu'on peut faire en java qu'on ne peut jamais faire en C#. Il me fallait juste le temps pour coder ces quelques linges de contre exemple:

    Première grande différence est la suivante: prenons les deux exemples qui suivent en faisant la correspondance que tu penses qu'ils sont égales entre Java et C#:
    On a notre classe MaClasse avec une seule méthode
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    namespace app{
    public class MaClasse{
     
            public void affiche(){
                Console.WriteLine("Affiche premier");
            }
        }
    }
    On fait une extension avec la classe suivante :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    namespace app {
     public static class ExtentionMaClasse{
     
            public static void affiche2(this MaClasse m){
                Console.WriteLine("Affiche deusieme ");
            }
        }
    }
    Alors on donne d'abord le code des déclarations en Java, voici le code de MaClasse qui implémente une interface vide que je nome Affichable;
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public class MaClasse implements  Affichable{ 
            public void affiche(){
                 System.out.println("Affiche premier");
            }    
    }
    Après je l’étend virtuellement en ajoutant une méthode par défaut affiche2() à Affichable, voici le code:
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public interface Affichable {
     
        default void affiche2(){
        System.out.println("Affiche deuxieme ");
            }
    }
    Alors à présent certes si je veux faire un appel classique de ces deux méthodes dans une classe Main le code sera identique que ça soit en Java ou C#:
    Code Java,C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MaClasse objet = new MaClasse ();
                    objet.affiche();
                    objet.affiche2();
    Résultat d'affichage pour les deux langages
    Affiche premier
    Affiche deuxieme
    Mais si je veux faire comme ça en C#:
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    namespace app
    {
        class MainClass
        {
            public static void Main(string[] args)
            {
                try {
                    MaClasse objet = new MaClasse ();
                    Type type = objet.GetType();
                    MethodInfo methode1 = type.GetMethod("affiche");
                    MethodInfo methode2 = type.GetMethod("affiche2");
                    //On a pas de paramètre pour nos méthodes
                    methode1.Invoke(objet,null);
                    methode2.Invoke(objet,null);//DEGAT DEGAT!!!
                } catch (NullReferenceException e) {
                    Console.WriteLine("Ça ne va pas dutout"); }
            }
        }
    }
    Et ben j'aurais bien ceci:
    Affiche premier
    Ça ne va pas dutout
    Et pourtant en Java si je fais ça:
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class MainClass {
     
        public static void main(String[] args) {
     
            try {
                MaClasse objet = new MaClasse ();
                Class<?> c=objet.getClass();
                Method methode1 = c.getMethod("affiche",null);
                Method methode2 = c.getMethod("affiche2",null);
                //Il n y a pas de paramètre donc j'utilise la méthode qui n'exige pas de paramètre
                methode1.invoke(objet);  
                methode2.invoke(objet);
            } catch (IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException ex) {
                System.err.println("Ça ne va pas du tout");
            }          
        }
    }
    J'aurais bien ça:
    Affiche premier
    Affiche deuxieme
    Ainsi, par réflexivité la réalité apparaisse, ce qui constitue une grande différence, je n'ai pas fait de substitution et voila le résultat correcte en Java. Par contre en C# j'obtiens juste ça

    La 2e grande différence, c'est que quand je suis dans l'interface alors je suis bien dans un contexte qui représente toutes les classes et toute la descendance qui implémentent l'interface encours, ainsi à l'intérieur de la méthode par défaut je peux faire référence à n'importe quel type héritant déjà existant si je veux.

    Pour cela, dans un contexte purement objet, en cas de besoin, j'accède à toutes les informations avec « this », pas besoin de passer quelque chose statiquement en paramètre d'une fonction.

    Déjà, certes je ne peux pas accéder à la limite aux attributs privés sans substitution, mais avant tout les attributs privés ne sont destinés à être utilisés qu'à l'intérieur de la classe qui les définit.

    Mais en plus de l'accès à n'importe quel méthode ou toute information disponible, je peux accéder avec « this » aussi aux attributs protégés d'une classe fille, selon le contexte d'attribut protégé définit par Java. Le plus important ici c'est que :« this » représente aussi une référence sur n’importe quel instance encours dont la classe fait partie de la descendance.

    Pour cela je peux faire facilement ce qui suit, d'abord j'ajoute un attribut protégé à MaClasse que je nomme val:
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class MaClasse implements  Affichable{ 
    protected String val="MaValeur";
            public void affiche(){
                 System.out.println("Affiche premier");           
            }    
    }
    Et voila le code de ma méthode par défaut:
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public interface Affichable {   
        default void affiche2(){  
        if(this instanceof MaClasse){//Pour aller droit au but et éviter les bug qui n'ont pas de sens
            //Je fais un cast sur this
        System.out.println ("Affiche deuxieme avec valeur="+((MaClasse)this).val);
        }
        }
    }
    Alors, ce bout de code compile en toute tranquillité et si je fais ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MaClasse objet = new MaClasse ();
                     objet.affiche2();
    Ça m'affiche bien ceci:
    Affiche deuxieme avec valeur=MaValeur
    En conclusion, les deux concepts n'ont rien de commun que le fait que je les appels tous les deux méthodes et qu'ils se ressemblent syntaxiquement lors d'un appel classique.

    Pour moi l'équivalent des méthodes d’extension en C# c'est tout simplement le surcharge d'opérateur en C++ un peu plus étendu qu'en C#, lorsque par exemple je surcharge une méthode static comme le flux de sortie de l'objet cout de type ostream, au lieu que je pusse juste faire seulement:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    cout<<"chaine"<<"2echaine";
    Je peux faire
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    cout<<objet<<"chaine"<<objet2<<...; //Et tout a été défini
    C'est comme si on étend le type ostream avec une méthode dont la signature n'est autre qu'un surcharge de l’opérateur «<<» qui accepte en 2e paramètre un type autre qu'un pointeur sur char et qui retourne aussi la référence de l'objet de type ostream passé en 1e paramètre.

    Ainsi, comme en C# l'opérateur «.» faisait partie de la liste d'exception des opérateurs non surchargeables, alors ils ont crée un mécanisme de le surcharger. Au lieu de faire ça maMethode(objet,params) pouvoir faire beau et faire objet.maMethode(params)

    Déjà je ne pense pas qu'il fallait appeler ces méthodes des méthodes d’extension, on étend jamais une classe en la faisant passer en paramètre d'une méthode statique, il fallait juste dire des méthodes statiques surchargés syntaxiquement.

  8. #28
    Expert éminent
    Avatar de Matthieu Vergne
    Homme Profil pro
    Consultant IT, chercheur IA indépendant
    Inscrit en
    Novembre 2011
    Messages
    2 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant IT, chercheur IA indépendant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 2 264
    Points : 7 760
    Points
    7 760
    Billets dans le blog
    3
    Par défaut
    Java 8, je te passe la bague au doigt... Enfin j'aimerais, mais hélas je dois faire attention à ce que mes programmes tournent encore sous Java 6 au boulot... Mais bon Dieux ce que ça me démange d'y passer ! {>.<}
    Site perso
    Recommandations pour débattre sainement

    Références récurrentes :
    The Cambridge Handbook of Expertise and Expert Performance
    L’Art d’avoir toujours raison (ou ce qu'il faut éviter pour pas que je vous saute à la gorge {^_^})

  9. #29
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Le JDK 8 u5 est disponible depuis le 15 avril. Cette mise à jour ne contient que des correctifs liés à la sécurité.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  10. #30
    Candidat au Club
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2014
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Types fonctionnels
    L'usage des interfaces comme types fonctionnels introduit malgré tout une certaine lourdeur syntaxique lors de l'appel d'une fonction. Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function<String, String> laPuissanceDeLaFonc = String::toUpperCase;
     
    System.out.println( laPuissanceDeLaFonc.apply("tion") );    // TION
    C'est le passage par cette méthode intermédiaire qui n'est pas trop naturel. (cf. argumentation détaillée sur http://au.arena.free.fr/blog/index.p...fonctionnelles )

    On aurait plutôt attendu qqch comme laPuissanceDeLaFonc("tion") comme en CAML ou Scala par exemple. Mais bon... en contrepartie les méthodes par défaut des interfaces du package 'java.util.function' apportent des mécanismes intéressants comme des types composés (ex: méthodes andThen ).

  11. #31
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par aurelien360 Voir le message
    C'est le passage par cette méthode intermédiaire qui n'est pas trop naturel. (cf. argumentation détaillée sur http://au.arena.free.fr/blog/index.p...fonctionnelles )

    On aurait plutôt attendu qqch comme laPuissanceDeLaFonc("tion") comme en CAML ou Scala par exemple.
    Je peux comprendre que cela puisse "choquer" si on est habitué à utiliser des langages comme CAML ou Scala qui intègre ces notions...

    Tu peux peut-être trouver cela "pas trop naturel", mais c'est juste la manière dont on appelle une méthode en Java.
    Ton laPuissanceDeLaFonc("tion") est peut-être plus court, mais il en devient aussi plus ambigüe...


    Ce choix d'implémentation est justement un des points que j'apprécie particulièrement dans les lambda de Java :
    • Très peu de modification syntaxique (si ce n'est la déclaration de la lambda en elle même bien sûr).
    • Pas de "type-fonction", donc pas de nouveau type à gérer, et pas de distinction entre un "type-fonction" et un objet.
    • Et donc une rétrocompatibilité implicite avec un grand nombre de librairie existante, puisque le concept d'interface fonctionnelle existait déjà même si on ne le nommait pas.



    a++

  12. #32
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par aurelien360 Voir le message
    L'usage des interfaces comme types fonctionnels introduit malgré tout une certaine lourdeur syntaxique lors de l'appel d'une fonction. Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function<String, String> laPuissanceDeLaFonc = String::toUpperCase;
     
    System.out.println( laPuissanceDeLaFonc.apply("tion") );    // TION
    C'est le passage par cette méthode intermédiaire qui n'est pas trop naturel. (cf. argumentation détaillée sur http://au.arena.free.fr/blog/index.p...fonctionnelles )

    On aurait plutôt attendu qqch comme laPuissanceDeLaFonc("tion") comme en CAML ou Scala par exemple. Mais bon... en contrepartie les méthodes par défaut des interfaces du package 'java.util.function' apportent des mécanismes intéressants comme des types composés (ex: méthodes andThen ).
    Je développe en C#, où les delegates s'utilisent aussi avec la syntaxe laPuissanceDeLaFonc("tion") (en réalité c'est juste un raccourci syntaxique pour laPuissanceDeLaFonc.Invoke("tion")), mais l'approche choisie par Java ne me choque pas. C'est un peu moins concis, mais ça a l'avantage de montrer clairement ce que fait la fonction, même si le développeur a choisi un nom de variable pas très clair.

  13. #33
    Candidat au Club
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Décembre 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Décembre 2014
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Ce choix d'implémentation est justement un des points que j'apprécie particulièrement dans les lambda de Java :
    • Très peu de modification syntaxique (si ce n'est la déclaration de la lambda en elle même bien sûr).
    • Pas de "type-fonction", donc pas de nouveau type à gérer, et pas de distinction entre un "type-fonction" et un objet.
    • Et donc une rétrocompatibilité implicite avec un grand nombre de librairie existante, puisque le concept d'interface fonctionnelle existait déjà même si on ne le nommait pas.
    1)Assez d'accord avec les points ci-dessus. Il est certain que "en contexte" (contraintes de compatibilité, introduction d'un nouveau paradigme sur un paradigme existant...), ces choix se défendent probablement. J'ajouterai encore et en plus l'intérêt des méthodes par défaut qui embarquées au niveau des types fonctionnels.

    2)Dans l'absolu cette fois, ce n'est pas tant la comparaison syntaxique avec d'autres langages comme Scala ou CAML mais plutôt la divergence conceptuelle avec la théorie derrière (lambda calcul ou simplement en math). Une fonction n'est pas définie et manipulée de cette manière.

    CONCL: Je pense que ces deux remarques se défendent de manière légitime.

Discussions similaires

  1. Quelle API Java pour un jeu de plate forme 2D ?
    Par dawadam dans le forum API graphiques
    Réponses: 0
    Dernier message: 16/06/2011, 22h25
  2. [java] Moteur de jeu de plate-forme
    Par luckyvae dans le forum Projets
    Réponses: 12
    Dernier message: 15/08/2007, 22h06
  3. Message: 'ce symbole est propre à une plate-forme'
    Par neho88 dans le forum Delphi
    Réponses: 4
    Dernier message: 18/10/2006, 15h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo