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

JavaScript Discussion :

[OO] Implémentation de l'héritage ET d'appels super()


Sujet :

JavaScript

  1. #1
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 253
    Points : 84
    Points
    84
    Par défaut [OO] Implémentation de l'héritage ET d'appels super()
    Bonjour à tous,

    J'utilise actuellement le script de John Resig pour fournir de l'héritage à mes "classes" Javascript mais sa méthode de déclaration par objet littéral ne permet pas de fourni des fonctionnalités intéressantes en termes de scope (i.e. les variable sont uniquement publiques et on ne peut pas faire de différence entre publique/privée, etc... sans déclarer ça à côté, après la déclaration de l'objet -> dégeulasse).

    Je cherche donc une manière de déclarer mes classes sous forme de fonction où il est possible de différencier les scopes comme évoqué dans cet article : Robert Nymann.

    Mais voila, je perds un aspect important de la programmation objet à mon sens : l'appel à super() que Resig inclue nativement dans son script.
    Je ne vois pas comment le reproduire lorsque les classes sont déclarées comme Robert Nymann le préconise.

    Est-ce que quelqu'un aurait une idée, l'a déjà réalisé? Ca me permettrai à la fois d'avoir les scopes, plus l'héritage et super (qui ne nécessite pas de répendre le nom de la classe parent à tous les 4 coins du fichier sinon en effet il est facile de reproduire cet appel avec le prototype du parent).
    En vous remerciant par avance, je sais que JS n'est pas un langage à vocation à faire de l'objet mais vu qu'on peut y arriver je saisi l'opportunité comme je le peux.

  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 418
    Points
    91 418
    Billets dans le blog
    20
    Par défaut
    je sais que JS n'est pas un langage à vocation à faire de l'objet
    Heu... si au contraire
    Sauf que ce n'est pas de l'OO par classes mais par prototype.
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  3. #3
    Membre expérimenté Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Points : 1 519
    Points
    1 519
    Par défaut
    J'avais fais un truc du genre y'a un an (mon niveau JS était pas terrible en fait à l’époque) donc si je devais le refaire aujourd'hui, je le ferai différemment et bien mieux.
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(a='eval(a)')
    recursive make it evil
    eval make it eval

  4. #4
    Invité
    Invité(e)
    Par défaut
    salut,

    je nuance le commentaire de Bovino.
    Javascript n'est pas spécifiquement orienté objet par prototype.

    Il est possible de faire l'objet. Mais il faut juste aborder l'OO de manière différente de la classique.

    Bien sûr, il est possible de se rapprocher du fonctionnement classique par l'approche prototypale, mais bon, (à ma connaissance), il reste les problèmes de propriétés privées & cie.

    De la même manière une approche uniquement par closure, limite l'approche par super (problème de scope en héritant de fonctions etc), et quand bien même atteinte nécessite de passer par une librarie etc.

    Je pense donc, que vouloir l'approche classique habituelle est mauvaise. Personnellement, je suis plutot fan de l'approche par closure, avec le passage en parametre d'un objet publique partagé parmi la hiérarchie. La raison qui me motive ezt que globalement, il n'y a pas tant que ça de niveau de hiérarchie, (deux ou trois tout au plus), et qu'il faut plutot favoriser beaucoup de composants (par composition justement) plutot qu'une structure verticale.

    Dans ce cas là, certes il faut être cohérent en jonglant in-hiérarchie, mais ca permet de s'en sortir plutot pas mal. Après, c'est vrai qu'il faut réfléchir à ce qu'on fait, et que je manque d'expérience sur des projets d'envergure relative.

  5. #5
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 418
    Points
    91 418
    Billets dans le blog
    20
    Par défaut
    Javascript n'est pas spécifiquement orienté objet par prototype.
    Euh... si, c'est même comme ça qu'il est défini.
    En JavaScript, non seulement tout est objet, mais aussi tout possède un prototype. Ensuite, en fonction de ce que l'on fait, il est possible, à l'instar de Mr Jourdain, de faire de l'OO sans le savoir (puisque souvent, on utilise majoritairement des prototypes natifs de JavaScript : String, Number, Function, etc.) mais c'est surtout l'approche procédurale qui n'existe pas à proprement parler en JavaScript.

    Et du coup, je trouve que vouloir reproduire en JavaScript le comportement d'un langage OO par classes est aller à l'encontre de la nature du langage et me semble assez maladroit en général. D'autant que de mémoire, je ne me souviens pas d'un cas où cela m'aurait réellement été utile.

    Ensuite, oui, il est possible de "simuler" des propriétés et méthodes privées et publiques (voire protégées).

    Quant à l'héritage, il se fait simplement par le prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var MaPseudoClasse = function(){};
    MaPseudoClasse.prototype = String.prototype;
    var toto = new MaPseudoClasse();
    alert(toto.toUpperCase);
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  6. #6
    Invité
    Invité(e)
    Par défaut
    Euh... si, c'est même comme ça qu'il est défini.
    En JavaScript, non seulement tout est objet, mais aussi tout possède un prototype
    ui forcément si toute fonction a pour prototype un object (qqsoit le degré de profondeur) l'instanciation va créer un objet.

    En REVANCHE, créer une simple constructeur de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function propper(){
     return {
      propr1:'oui';
     };
    };
    permet de créer un objet avec lequel il ne sera pas possible d'avoir un prototype "personnalisable" sur l'objet retourné dans la mesure ou le constructeur est déclaré à la volée.

    D'autant que de mémoire, je ne me souviens pas d'un cas où cela m'aurait réellement été utile.
    Voilà un exemple très simple sur lequel j'ai été confronté (peut-être que j'ai pas vu assez loin, c'est possible).

    Tu veux créer le jeu de la vie.
    On crée donc une fonction/constructeur automate.
    Il existe des automates synchrones et asynchrones (asynchrones pour la fourmie de langton par exemple).

    On aurait donc envie de dev une interface du style, tick; refresh, qui actualise l'automate et le met à jour, ainsi que dans les classes filles de défininir tick, et refresh.

    Bon, clairement dans ce cas là, on peut avoir besoin de se servir des services du constructeur parent (dont l'approche classique serait de dire classe abstraite).

    Une approche prototypale force les propriétés du parent et des filles à être publiques...
    une approche par closure permet de conserver les propriétés privées et de réutiliser les méthodes parent par l'objet publique passé en paramètre...

    La question de l'héritage me semble triviale par prototype.
    Dans le cas d'une approche par closure, on ne peut se contenter que d'un couple décorateur/paramètre publique, qui n'est pourtant pas si moche.

    Donc non, l'approche objet en javascript n'est pas forcément prototypale.

  7. #7
    Membre expérimenté Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Points : 1 519
    Points
    1 519
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Euh... si, c'est même comme ça qu'il est défini.
    En JavaScript, non seulement tout est objet, mais aussi tout possède un prototype. Ensuite, en fonction de ce que l'on fait, il est possible, à l'instar de Mr Jourdain, de faire de l'OO sans le savoir (puisque souvent, on utilise majoritairement des prototypes natifs de JavaScript : String, Number, Function, etc.) mais c'est surtout l'approche procédurale qui n'existe pas à proprement parler en JavaScript.

    Et du coup, je trouve que vouloir reproduire en JavaScript le comportement d'un langage OO par classes est aller à l'encontre de la nature du langage et me semble assez maladroit en général. D'autant que de mémoire, je ne me souviens pas d'un cas où cela m'aurait réellement été utile.

    Ensuite, oui, il est possible de "simuler" des propriétés et méthodes privées et publiques (voire protégées).

    Quant à l'héritage, il se fait simplement par le prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var MaPseudoClasse = function(){};
    MaPseudoClasse.prototype = String.prototype;
    var toto = new MaPseudoClasse();
    alert(toto.toUpperCase);
    Certaines méthodes sont déclaré en même temps que l'objet du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function ConstructeurObjet(){
        this.méthode = function(){alert("je suis inutile");};
    }
    Dans ce cas pour faire un 2 ème constructeur qui héritera de la méthode des objets du premier il faudra aussi faire des "call/apply" du ConstructeurObjet (parent).

    J'ai donc vite recodé tout ça qui à l'air de rudement bien répondre aux bases minimales :


    Code : 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
    Function.prototype.inherits = function(parent){ 
    	var FN = this;
    	var newFN = function(){
    		parent.apply(this,arguments);
    		this.super = this.super?{super:this.super}:{};
    		for(var i in this)
    			if(typeof this[i] == "function")
    				this.super[i] = this[i];
    		return FN.apply(this,arguments);
    	};	
    	var proto = function(){};
    	proto.prototype = parent.prototype;
    	newFN.prototype = new proto();
    	for(var i in FN.prototype)
    		newFN.prototype[i] = FN.prototype[i];
    	newFN.super = parent;
    	return newFN;
    };

    version avec qqes tests :
    Code html : 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    <html><head><script type=text/javascript>
     
     
    Function.prototype.inherits = function(parent){ 
    	var FN = this;
    	var newFN = function(){
    		parent.apply(this,arguments);
    		this.super = this.super?{super:this.super}:{};
    		for(var i in this)
    			if(typeof this[i] == "function")
    				this.super[i] = this[i];
    		return FN.apply(this,arguments);
    	};	
    	var proto = function(){};
    	proto.prototype = parent.prototype;
    	newFN.prototype = new proto();
    	for(var i in FN.prototype)
    		newFN.prototype[i] = FN.prototype[i];
    	newFN.super = parent;
    	return newFN;
    };
     
     
     
    //--------------------------------
     
    /*
    function A(){
    	var privat = "secret";
    	this.getPrivate = function(){return privat;};
    	return this;
    }
     
    function B(){
    	var privat = "nouveau secret";
    	this.public = "info public";
    	this.getPrivate = function(){return privat;};
    	return this;
    }
    B = B.inherits(A);
     
    // console.log
    var l = function(msg){console.log(msg);};
     
    var b = new B();
    l(b.super.getPrivate()); // secret
    l(b.getPrivate()); // nouveau secret
    l(b.public); // info public
    l(b instanceof A); // true
    l(b instanceof B); // true
    l("---------------------------------------------------");
    */
     
    //--------------------------------
     
     
    var wr = function(val){document.write(val,"<hr>");}; 
     
    function A(){
    	this.a=1;
    	this.aa=function(){wr("aa");};
    	this.obj={val:97};
    	this.hard=function(c){
    		wr("a.hard: "+c);
    	};
    	return this;
    }  
    A.prototype.fun = 11; 
    function B(name){
    	this.b=2;
    	this.bb=function(){wr("bb");};
    	this.name=name;
    	this.hard=function(v){
    		wr("b.hard: "+v);
    		this.super.hard(name);
    	};
    	return this;
    }  
    function O(){
    	this.o=3;
    	this.oo=function(){wr("oo");};
    	return this;
    }  
    function H(){
    	this.h=4;
    	this.aa=function(){wr("hh");};
    	this.oo=function(){wr("hh");};
    	return this;
    }  
    H.prototype.fun = 22; 
    var B = B.inherits(A); 
    var H = H.inherits(B);  
    var H = H.inherits(O);  
     
    var h = new H("john smith");  
     
     
     
    wr("=============== FOR EACH IN ( h ) ==============="); 
    for(var i in h)    wr(i+": "+h[i]);  
    // a: 1  
    // b: 2  
    // o: 3  
    // h: 4  
    // func aa : wr hh  
    // func bb : wr bb  
    // func oo : wr hh  
    // parentFN :  ############### object 
    // obj :    object 
    // name : "john smith"  
    // uber :  ############# function 
     
    // overwrited functions  
    wr("=============== OVERWRITED FUNCTIONS ==============="); 
    h.aa(); // hh   
    h.oo(); // hh  
    wr("=============== SUPER/ORIGINAL FUNCTIONS ==============="); 
    // super functions who been overwrited  
    h.super.aa(); // aa  
    h.super.oo(); // oo  
    wr("=============== HERITED FUNCTIONS ==============="); 
    // herited function  
    h.bb(); // bb  
    wr("=============== OBJECTS FROM 2 DIFFERENT INSTANCES ==============="); 
    // test if object1.obj != object2.obj 
    var h2 = new H();  
    h2.obj.val++;  
    wr(h2.obj.val); // 98  
    wr(h.obj.val); // 97  
    wr("=============== PARENTS PROTOTYPE AREN'T MODIFIED ON CHANGE OF CHILD PROTOTYPE ==============="); 
    var a = new A(); 
    wr(a.fun); 
    wr(h.fun); 
    wr("=============== FINAL TEST ==============="); 
    h.hard("Happy End");
     
    </script></head><body></body></html>

    edit: remplacez "super" par un autre mot (uber ou _super) dans le code car je pense que "super" est un mot clé.
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(a='eval(a)')
    recursive make it evil
    eval make it eval

  8. #8
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 418
    Points
    91 418
    Billets dans le blog
    20
    Par défaut
    @galerien69 : ta fonction propper n'est pas un constructeur
    Un constructeur doit servir à créer des instances de ce constructeur. Ici, il me semble que tu confonds un objet en tant qu'instance de l'objet natif Object et un objet en tant qu'instance d'un constructeur.
    Du coup, pour personnaliser le prototype, c'est celui d'Object qu'il faut utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function propper(){
     return {
      propr1:'oui'
     };
    };
    Object.prototype.deny = function(){
        this.propr1 = 'non'
    };
    var sayYes = new propper();
    alert(sayYes.propr1);
    sayYes.deny();
    alert(sayYes.propr1);


    @fanfouer : désolé si on empiète sur ta question, mais la discussion est intéressante
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  9. #9
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 418
    Points
    91 418
    Billets dans le blog
    20
    Par défaut
    Citation Envoyé par Willpower
    edit: remplacez "super" par un autre mot (uber ou _super) dans le code car je pense que "super" est un mot clé.
    Non, ce n'est pas un mot clé mais un mot reservé
    Etonnamment, JavaScript se réserve (pour d'éventuelles évolutions futures) la plupart des mots clés habituellement utilisés en POO par classes. D'où d'ailleurs la propriété des objets HTMLElement className pour éviter d'utiliser class

    Certaines méthodes sont déclaré en même temps que l'objet
    Oui, elles en deviennent du coup des équivalents de méthodes privées qui dépendent de l'instance de l'objet et non du constructeur (et donc du prototype). Mais il est à noter que si rien n'individualise ces méthodes, leur utilisation est déconseillée car ça oblige à redéfinir une fonction pour chaque instance plutôt que d'utiliser la même si elle est déclarée dans le prototype
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  10. #10
    Invité
    Invité(e)
    Par défaut
    Du coup, pour personnaliser le prototype, c'est celui d'Object qu'il faut utiliser :
    Tu discutailles sur le vocabulaire.
    Donc la fonction propper, elle construit bien un object. C'est en ce sens que je l'appèle constructeur, même si c'est vrai que le mot clé new n'est pas nécessaire.

    Pour ce qui est d'étendre l'objet par prototype, oui ca serait la solution technique, je pense que nous savons tous deux, que ce n'est pas très joli.

  11. #11
    Membre expérimenté Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Points : 1 519
    Points
    1 519
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Oui, elles en deviennent du coup des équivalents de méthodes privées qui dépendent de l'instance de l'objet et non du constructeur (et donc du prototype). Mais il est à noter que si rien n'individualise ces méthodes, leur utilisation est déconseillée car ça oblige à redéfinir une fonction pour chaque instance plutôt que d'utiliser la même si elle est déclarée dans le prototype
    Pas forcément redéfini si l'on a des référence à une méthode publique déclarées lors de la construction des objets. Par exemple si la méthode publique risque de disparaître ou d'être remplacée par la suite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function saveMethode(name){
    	this.original = window[name];
    }
    var myAlert = new saveMethode("alert");
    myAlert.original.call(window,"appel à alert");
    alert = function(){};
    alert("\0/");
    Mon exemple est affreux mais aucune fonction n'est redéfini dans mon objet et un prototype ne conviendrai pas. Bon je suis sûr que dans ce cas il y a mieux à faire mais je suis également persuadé qu'il existe des cas où il est utile de déclarer des fonction(ou référence) lors de l'instanciation d'objets.
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(a='eval(a)')
    recursive make it evil
    eval make it eval

  12. #12
    Invité
    Invité(e)
    Par défaut
    a chaque que je voit une conversation sur la poo je me dit que c'est vraiment de la merde car il n'y a jamais reelement de resolution au probleme et que l'on se retrouve rapidement dans du charabia qui ne motive pas a apprendre la poo car si on l'apprend et au finale on se retrouver a se poser un miliard de questions a savoir quelle est la meilleur facon d'utiliser la poo pourquoi l'apprendre ? sans compter que l'on ne voit jamais d'exemple pratique reel a l'inverse du virtuelle que l'on rencontre tout le temp dans son utilisation.

    et vive le procedurale

  13. #13
    Invité
    Invité(e)
    Par défaut
    bjr,

    deux remarques pour le script de willpower.

    On a vu (enfin je lui fais confiance!) que les variables peuvent être privées. Egalement publiques. Elles ne peuvent pas être protected, (cad accéder à une variable parent uniquement par ses fils).

    Concernant la remarque des références, je veux bien savoir comment on pourrait s'en sortir en faisant qqch de joli, parce que si c'est pour voir un saverManager dans un gUtils.... S'il y a quelque chose de stylé ça m'intéresse.

    je suis également persuadé qu'il existe des cas où il est utile de déclarer des fonction(ou référence) lors de l'instanciation d'objets
    tout simplement pour des variables privées. et éviter d'avoir un accesseur publique

  14. #14
    Membre expérimenté Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Points : 1 519
    Points
    1 519
    Par défaut
    Citation Envoyé par mekal Voir le message
    a chaque que je voit une conversation sur la poo je me dit que c'est vraiment de la merde car il n'y a jamais reelement de resolution au probleme et que l'on se retrouve rapidement dans du charabia qui ne motive pas a apprendre la poo car si on l'apprend et au finale on se retrouver a se poser un miliard de questions a savoir quelle est la meilleur facon d'utiliser la poo pourquoi l'apprendre ? sans compter que l'on ne voit jamais d'exemple pratique reel a l'inverse du virtuelle que l'on rencontre tout le temp dans son utilisation.

    et vive le procedurale
    Je peux t'assurer que la POO est très utile de façon concrète et simple. (enfin surtout pour les applications de grande envergure )

    Le problème ici en javascript est que beaucoup veulent souvent essayer d'adopter son approche par classe comme dans les autres langages alors évidement ça pose problème plutôt que simplement se plier aux outils de prototype offert par javascript et tout aussi puissant.
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(a='eval(a)')
    recursive make it evil
    eval make it eval

  15. #15
    Invité
    Invité(e)
    Par défaut
    ben honnêtement, je trouve que l'inherits proposé n'est pas pertinent (trop complexe). Ca fait joli, on peut redéfinir des méthodes, avoir super, d'une façon "classique".

    mais bon, on peut très bien aborder le problème par composition...à la manière d'un décorateur. Tant pis pour les calls à upperMethode.

  16. #16
    Membre expérimenté Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Points : 1 519
    Points
    1 519
    Par défaut
    Citation Envoyé par galerien69 Voir le message
    bjr,

    deux remarques pour le script de willpower.

    On a vu (enfin je lui fais confiance!) que les variables peuvent être privées. Egalement publiques. Elles ne peuvent pas être protected, (cad accéder à une variable parent uniquement par ses fils).

    Concernant la remarque des références, je veux bien savoir comment on pourrait s'en sortir en faisant qqch de joli, parce que si c'est pour voir un saverManager dans un gUtils.... S'il y a quelque chose de stylé ça m'intéresse.
    Je ne connais pas gUtils et j'avoue ne pas bien saisir toutes tes remarques (j'suis encore mal réveillé)

    Sinon effectivement il n'existe pas réellement les notions de publique/privé en javascript. Ce sont plus des notions de scopes de variables. Enfin évidement que protected n'existe pas du fait que l'héritage n'existe pas et donc aucune règle pour définir un objet fils.

    tu peux néanmoins faire des trucs tordus qui s'en approchent:
    Code : 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
    20
    21
    function A(){
    	var private = function(){ alert("private"); };
    	this.privateGetter = function(){ private(); };
    	var protected = function(){ alert("protected"); };
    	// si l'appelant n'est pas new ou window, on surcharge donc un objet à qui on renvoie les données protected
    	if(this != window && !(this instanceof A))
    		return protected;
    }
     
    function B(){
    	// le call rajoute la méthode "getPrivate" au this("héritage") et retourne les méthodes "protégées" de A
    	var protected = A.call(this);
    	this.protectedGetter = function(){ protected(); };
    }
     
    var a = new A();
    a.privateGetter();
     
    var b = new B();
    b.protectedGetter();
    b.privateGetter();
    Citation Envoyé par galerien69 Voir le message
    tout simplement pour des variables privées. et éviter d'avoir un accesseur publique
    Oui, les getter/setter sont un bon exemple, bien vu. ^^
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(a='eval(a)')
    recursive make it evil
    eval make it eval

  17. #17
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 253
    Points : 84
    Points
    84
    Par défaut
    Whaou bonsoir messieurs (dames)

    Je ne souhaitais pas tant déchainer les foules mais merci d'avoir répondu présent.

    Je crois que l'approche Willpower (en complétant le prototype de Function) est intéressante.

    Sur le pourquoi de la chose : je développe quelque chose d'assez conséquent uniquement orienté objet. Ca a commencé en PHP, et c'est finalement destiné à être utilisé sur plusieurs plateformes donc plusieurs langages. Il serait dommage de modifier la structure de ce projet suivant le langage sachant que si une modification intervient, je vais devoir faire une étude pour toutes les implémentations.

    J'ai bien conscience que ma demande ne rentre pas dans les prérogatives de javascript (je suis bien d'accord avec le message de Bovino, je m'étais mal exprimé) mais je préfère gagner du temps par la suite sur ce coup.
    En outre, je ne mets pas n fonctionnements en jeu, pratique pour cibler un problème quelque soit l'édition du projet.

    Merci pour vos réponses, et n'hésitez pas à continuer le débat.

  18. #18
    Membre expérimenté Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Points : 1 519
    Points
    1 519
    Par défaut
    De rien, c'est un des sujets qui me passionne le plus ^^


    Code : 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
    20
    21
    22
    23
    var inherits = function(FN,parent,parentParent,Paren){ 
    	//var FN = this;
    	if(arguments.length>2)
    		parent = inherits.apply(this,[].slice.call(arguments,1));
    	var newFN = function(){
    		parent.apply(this,arguments);
    		this.super = this.super?{super:this.super}:{};
    		for(var i in this)
    			if(typeof this[i] == "function")
    				this.super[i] = this[i];//(function(obj,fnName){ return function(){ return obj[fnName].apply(this,arguments); }; })(this,i);
    		return FN.apply(this,arguments);
    	};	
    	var proto = function(){};
    	proto.prototype = parent.prototype;
    	newFN.prototype = new proto();
    	for(var i in FN.prototype)
    		newFN.prototype[i] = FN.prototype[i];
    	newFN.super = parent;
    	return newFN;
    };
    Function.prototype.inherits = function(){
    	return inherits.apply(window,[this].concat([].slice.call(arguments,0)));
    };
    Nouvelle version facilitant l'héritage multiple. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // f2 = f2.inherits(f1); 
    // f3 = f3.inherits(f2); 
    // f4 = f4.inherits(f3); 
    // f5 = f5.inherits(f4);
    var f5 = f5.inherits(f4,f3,f2,f1);
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(a='eval(a)')
    recursive make it evil
    eval make it eval

  19. #19
    Invité
    Invité(e)
    Par défaut
    dsl willpower, je voulais étayer mais l'apéro et tout se sont enchaînés...j'ai zappé.

    Donc par gUtils, c'est pas une librairie qui existe, c'est un pondu de mon imagination pour dire qu'en gros, avoir un truc qui gère les ref de fonctions, ca need d'aller dans une variable globale, (à la manière d'une librairie), et que du coup on pollue un peu windows pour des soucis d'optimisation.

    pour ce qui est de ta proposition pour les membres protégés, c'est intéressant, mais j'avouerais avoir du mal à faire l'application avec les constructeur. Quelle est la diff avec une méthode publique?

    Sinon, on peut extrapoler aux attributs de classes sans passer par des getters :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function A(){
    	var obj={};
            obj.perso='lol';
    	obj.protected = function(){ alert("protected"); };
    	// si l'appelant n'est pas new ou window, on surcharge donc un objet à qui on renvoie les données protected
    	if(this != window && !(this instanceof A))
    		return obj;
    }
    Et plus génériquement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function A(obj){
     //update obj
     return obj;
    }
    Quant au décorateur, j'entendais simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function A(param){
    	var obj={};
            //update param
            obj.perso='lol';
    	obj.protected = function(){ alert("protected"); };
    	return obj;
    }
    function B(){
      var myA = A({});
      myA.newMethod="lol";
      return myA;
    }

  20. #20
    Membre expérimenté Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Points : 1 519
    Points
    1 519
    Par défaut
    Citation Envoyé par galerien69 Voir le message
    dsl willpower, je voulais étayer mais l'apéro et tout se sont enchaînés...j'ai zappé.

    Donc par gUtils, c'est pas une librairie qui existe, c'est un pondu de mon imagination pour dire qu'en gros, avoir un truc qui gère les ref de fonctions, ca need d'aller dans une variable globale, (à la manière d'une librairie), et que du coup on pollue un peu windows pour des soucis d'optimisation.

    pour ce qui est de ta proposition pour les membres protégés, c'est intéressant, mais j'avouerais avoir du mal à faire l'application avec les constructeur. Quelle est la diff avec une méthode publique?

    Sinon, on peut extrapoler aux attributs de classes sans passer par des getters :
    si je ne me trompe pas, protected c'est private sauf que private n'est pas accessible aux enfants contrairement à protected.

    effectivement ta version est plus sympa (je n'avais jamais pensé à la chose avant de l'écrire en direct dans ce sujet donc ma version était précaire^^)

    par contre ton dernier exemple n'a plus grand chose à voir avec l'héritage, tu fais juste appel à un constructeur d'objet contenant des fonctions.

    en reprenant ton premier exemple ça donnerait donc :
    Code : 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    function A(){
    	var private = {
    		func1 : function(){ alert("private"); }
    	};
    	var protected = {
    		func1 : function(){ alert("protected"); }
    	};
    	var public = {
    		func1 : function(){ private.func1(); },
    	};
    	this.public = public;
     
    	// si l'appelant n'est pas new ou window, on surcharge donc un objet à qui on renvoie les données protected
    	if(this != window && !(this instanceof A))
    		return protected;
     
    	// else return this;
    }
     
    function B(){
    	// heritage de A
    	// le call fait hériter l'objet courant ("this") de la class A qui retourne ses méthodes protected
    	var protected = A.call(this);
    	var private = {};
    	with(this.public){
    		// surchage de la fonction public "func1" (définie par A)
    		func1 = function(){ protected.func1(); }
    	};
     
    	// si l'appelant n'est pas new ou window, on surcharge donc un objet à qui on renvoie les données protected
    	if(this != window && !(this instanceof B))
    		return protected;
     
    	// else return this;
    }
     
    //------ usage -----
     
    var a = new A();
    a.public.func1(); // private
     
    var b = new B();
    b.public.func1(); // protected
    tiens, j'suis ému, je trouve ça beau
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(a='eval(a)')
    recursive make it evil
    eval make it eval

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 4 1234 DernièreDernière

Discussions similaires

  1. Implémentation Runnable et héritage
    Par abdelilah dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 04/03/2010, 01h11
  2. Réponses: 8
    Dernier message: 10/11/2009, 21h41
  3. Héritage et d'appel de méthode
    Par Sunsawe dans le forum Langage
    Réponses: 11
    Dernier message: 30/07/2009, 23h08
  4. Réponses: 7
    Dernier message: 24/09/2008, 11h18
  5. Héritage : problème d'appel de méthodes
    Par parano dans le forum C++
    Réponses: 15
    Dernier message: 02/03/2007, 14h42

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