• [^] # Re: Java et Linux

    Posté par . En réponse au journal Java et Linux. Évalué à 2.

    C'était un exemple simple pour comprendre mais c'est raté il me semble :-/
    C'est un sujet un peut compliqué. Si on comprend bien les notions Objet c'est relativement facile à comprendre (mais plus dur à expliquer malheureusement pour moi).

    Je me place dans un modèle conceptuel qui n'a rien à voire avec l'implémentation (l'implémentation et la compilation efficace est un autre sujet, certes lié, mais qui n'a rien à voire) ni avec la syntaxe Java (car la syntaxe est addapté au comportement). En parlant d'introspection à la Java tu te limites au modèle Java qui forcément n'est pas addapté aux concepts étrangers à Java.

    Il faut savoir que la covariance ne change en rien le concept de spécialisation (héritage) ni de sous-classage. Par contre elle pose un problème avec la théorie des types qui est incompatible avec la covariance bien qu'il fut montré que c'est la théorie des types qui n'est pas addapté à la réalité (pour preuve l'existence du cas particulier des coercitions (cast)).

    Les règles de typage que respecte Java (en parti car Java n'est pas cohérent) est celle utilisé par presque tous les langages de programmation fortement typés.

    Tu emplois le mot « remplace ». deux sens possible pour un tel mot :
    1- redéfinition : une fonction toto qui a un comportement dans une classe A aquiert un comportement particulier (et spécialisé) dans une sous-classe B. Le polymorphisme marche.

    exemple :

    A v
    v = new B
    v.toto

    bien que toto soit appelée sur un objet de type statique A, c'est la fonction B::toto qui est exécuté car le type dynamique de v sera B.

    2- surcharge statique : une fonction toto qui a un comportement dans une class A est écrasée par une autre foction toto dans une sous-classe B. Les deux fonctions toto n'ont rien en commun si ce n'est le nom. Le polymorphisme ne marche pas.

    dans l'exemple précedent, c'est la fonction A::toto qui serait appelée.

    Ces deux définition de « remplacement » sont indépendante du modèle de variance du langage (puisque je n'ai pas parlé de paramètres).


    Maintenant un cas concret. En Java on doit écrire quelque chose du genre
    class Animal {
    void mange(Nouriture n);
    }
    class Carnassier {
    void mange(Nouriture n) {
    Animal a;
    a = (Animal)n; // je sais plus comment on fait les casts en Java :p
    // le reste
    }

    avec la covariance on aurait

    class Animal {
    void mange(Nouriture n);
    }
    class Carnassier {
    void mange(Animal a) {
    // le reste
    }

    Tout chose étant égale par ailleurs.

    Quel est l'interet ?
    - autospécification des paramètres ;
    - plus besoin de cast ;
    - pas besoin de se trainer une signature qui n'a presque plus rien à voire avec son utilisation dans une petite petite sous-classe.

    Limitation : la surcharge statique devient impossible. Mais c'est pas un mal car il n'y a plus ambiguité entre redéfinition et surcharge statique : le modèle est plus clair. (la surcharge statique est souvent décriée).

    Remarque, la covariance du type de retour n'est pas non plus incluse dans Java malgrè que :
    - la covariance du type de retour est compatible avec la théorie des types (si si) ;
    - le cout d'implémentation dans langage à héritage simple est négligeable. D'ailleurs en C++ cette coraviance est dans la norme mais peu de compilo l'implémentent car le coût est sans commune mesure en héritage multiple. Au dernières nouvelles g++ nous sortait un message d'excuse :)