Faculté I&C, Claude Petitpierre, André Maurer 1 Héritage par prototype Héritage dattributs ou de méthodes Héritage de constructeurs
Faculté I&C, Claude Petitpierre, André Maurer 2 Héritage de méthodes function Constructeur() { this.m1 = function () {... } } Constructeur.prototype.m2 = function () {... } var x = new Constructeur() var y = new Constructeur() x.m2() y.m2() objet construit this.m1 prototype m1() m2() Le lien nest pas directement accessible par le programme Un sous-objet (attribut) prototype est automatiquement créé dans chaque fonction x objet construit this.m1 y m1()
Faculté I&C, Claude Petitpierre, André Maurer 3 Héritage de méthodes function Constructeur() { this.m1 = function () {... } } Constructeur.prototype.m2 = function () {... } var x = new Constructeur() Constructeur.prototype.m3 = function () {... } // après la création x.m1() x.m2() x.m3() Constructeur this.m1 prototype m1() m3() m2()
Faculté I&C, Claude Petitpierre, André Maurer 4 Héritage dattributs function Constructeur() { this.a = 12 } Constructeur.prototype.b = 13 var x = new Constructeur() Constructeur.prototype.c = 14 alert ( x.a +" " + x.b+" "+x.c ) objet construit this.a prototype b c x
Faculté I&C, Claude Petitpierre, André Maurer 5 Ré-écriture des attributs ! objet construit this.a prototype a function Constructeur() { } Constructeur.prototype.a = 13 var x = new Constructeur() var y = new Constructeur() alert(x.a) // 13 x.a = 14 alert(x.a) // 14 alert(y.a) // 13 x.a = 14 Chaque objet lit la valeur initiale, jusquà ce quil la change. Chaque objet a sa propre valeur. x
Faculté I&C, Claude Petitpierre, André Maurer 6 Tableaux ou objet dans les prototypes ! Constructeur prototype a [13] function Constructeur() { } Constructeur.prototype.a = [ ] var x = new Constructeur() var y = new Constructeur() x.a[0] = 13 alert( y.a[0] ) // aussi 13 Les tableaux et les objets sont donc mis en commun x objet construit y
Faculté I&C, Claude Petitpierre, André Maurer 7 Création dun nouveau tableau ou objet dans un prototype objet construit prototype a[12] function Constructeur() { } Constructeur.prototype.a = [12] var x = new Constructeur() var y = new Constructeur() x.a = [8] // nouvel attribut alert(y.a) // 12, ancienne valeur x objet construit y a[8] a[12] objet construit y
Faculté I&C, Claude Petitpierre, André Maurer 8 Incrémentation dun attribut dans un prototype objet construit a prototype a function Constructeur() { } Constructeur.prototype.a = 12 var x = new Constructeur() var y = new Constructeur() x.a++ // équivalent à x.a = x.a+1 alert(y.a) // 12, ancienne valeur objet construit y x
Faculté I&C, Claude Petitpierre, André Maurer 9 Héritage de constructeurs prototype function Constructeur1() { this.m1 = function() {...} } function Constructeur2() { this.m2 = function() {...} } Constructeur2.prototype = new Constructeur1() var x = new Constructeur2() x.m1() x.m2() objet construit 2 m2 prototype m1 x function constructeur1 construit function
Faculté I&C, Claude Petitpierre, André Maurer 10 Exemple ( pas darguments ) function Translation() { this.tPrint = function() { ctx.save() ctx.translate(90, 90) this.print() ctx.restore() } } function Cercle(x,y,r) { this.print = function() { ctx.beginPath() ctx.arc(x,y,r,0,2*Math.PI,true) ctx.stroke() } } Cercle.prototype = new Translation() function execute() { var cercle1 = new Cercle(50,50,15) cercle1.tPrint() cercle1.print() }
Faculté I&C, Claude Petitpierre, André Maurer 11 Exemple ( avec initialisation, « super » en Java ) function Translation() { this.tPrint = function() { ctx.save() ctx.translate(this.xt,this.yt) this.print() ctx.restore() } this.initTranslation = function(xt,yt) { this.xt = xt this.yt = yt } } function Cercle(x,y,r,xt,yt) { this.initTranslation(xt,yt) // super(xt,yt) this.print = function() { ctx.beginPath() ctx.arc(x,y,r,0,2*Math.PI,true) ctx.stroke() } } Cercle.prototype = new Translation() function execute() { var cercle1 = new Cercle(50,50,15,0,0) cercle1.tPrint() var cercle2 = new Cercle(50,55,15,90,90) cercle2.tPrint() }
Faculté I&C, Claude Petitpierre, André Maurer 12 Appel de super-classe à sub-classe ou vice-versa Translation tPrint() { } Cercle print() Translation open() close() Cercle print() { } this signe de lhéritage
Faculté I&C, Claude Petitpierre, André Maurer 13 Exemple function Translation() { this.open = function(xt,yt) { ctx.save() ctx.beginPath() ctx.translate(xt,yt) } this.close = function() { ctx.stroke() ctx.restore() } } function Cercle(x,y,r,xt,yt) { this.print = function() { this.open(xt,yt) ctx.arc(x,y,r,0,2*Math.PI,true) this.close() } } Cercle.prototype = new Translation() function execute() { var cercle1 = new Cercle(50,50,15) cercle1.print() cercle2.print() }
Faculté I&C, Claude Petitpierre, André Maurer 14 Prototype avec méthodes ( première des deux solutions précédentes ) function Translation() { } Translation.prototype.initTranslation = function(xt,yt) { this.xt = xt this.yt = yt } Translation.prototype.tPrint = function() { ctx.save() ctx.translate(this.xt,this.yt) this.print() ctx.restore() }... function Cercle(x,y,r,xt,yt) { this.x = x this.y = y this.r = r this.initTranslation(xt,yt) } Cercle.prototype = new Translation() Cercle.prototype.print = function() { ctx.beginPath() ctx.arc(this.x,this.y,this.r,0,2*Math.PI,true) ctx.stroke() }
Faculté I&C, Claude Petitpierre, André Maurer 15 Effet pervers function Groupe() { this.arr = [ ] } function Cercle(x,y,r) { this.x = x } Cercle.prototype = new Groupe() var c1 = new Cercle(10,20,3) var c2 = new Cercle(20,12,3) c1.arr[0] = 12 c2.arr[0] == 12 // arr est devenu commun !! Solution:initialiser les tableaux et les objets dans la méthode dinitialisation
Faculté I&C, Claude Petitpierre, André Maurer 16 Exemple des objets graphiques Cercle, rectangle… Groupes Transformations Sauvetage des dessins Détection
Faculté I&C, Claude Petitpierre, André Maurer 17 Hiérarchie de groupes et cercles avec rotations function execute() { groupeDeBase = new Groupe(0,0,0) groupeDeBase.liste.push(new Cercle(80,120,15,0,0,0)) groupeDeBase.liste.push(new Cercle(120,120,15,0,0,0)) groupeDeBase.liste.push(new Cercle(120,80,15,0,0,0)) groupeDeBase.liste.push(new Cercle(80,80,15,0,0,0)) var groupe2 = new Groupe(200,100,0.3) groupeDeBase.liste.push(groupe2) groupe2.liste.push(new Cercle( 220,80,10,0,0,0)) groupe2.liste.push(new Cercle( 180,80,10,0,0,0)) groupeDeBase.tPrint() }
Faculté I&C, Claude Petitpierre, André Maurer 18 Même hiérarchie en SVG <circle id="circ" cx="80" cy="80" r="15" stroke="red" fill="none" transform='rotate(0,0,0)' />
Faculté I&C, Claude Petitpierre, André Maurer 19 function Transformation() { this.tPrint = function() { ctx.save() ctx.translate(this.xt,this.yt) this.print() ctx.restore() } } function Cercle(x,y,r,xt,yt) { this.print = function() { ctx.beginPath() ctx.arc(x,y,r,0,2*Math.PI,true) ctx.stroke() } } Interactions des objets ( sans transformations ) function Transformation() { this.tPrint = function() { ctx.save() ctx.translate(this.xt,this.yt) this.print() ctx.restore() } } function Groupe(xt,yt) { this.print = function () { for (var i=0; i<this.liste.length; i++) { this.liste[i].tPrint() } } }
Faculté I&C, Claude Petitpierre, André Maurer 20 Diagramme dobjets GroupeCercle GroupeCercle // Affichage des groupes this.print = function () { for (var i=0; i<this.liste.length; i++) { this.liste[i].print() } }
Faculté I&C, Claude Petitpierre, André Maurer 21 function Transformation() { this.tPrint = function() { ctx.save() ctx.translate(this.xt,this.yt) this.print() ctx.restore() } } function Cercle(x,y,r,xt,yt) { this.print = function() { ctx.beginPath() ctx.arc(x,y,r,0,2*Math.PI,true) ctx.stroke() } } Interactions des objets function Transformation() { this.tPrint = function() { ctx.save() ctx.translate(this.xt,this.yt) this.print() ctx.restore() } } function Groupe(xt,yt) { this.print = function () { for (var i=0; i<this.liste.length; i++) { this.liste[i].tPrint() } } }
Faculté I&C, Claude Petitpierre, André Maurer 22 Diagramme dobjets Rotation Groupe Rotation Cercle Rotation Cercle Rotation Cercle Rotation Groupe Rotation Cercle Rotation Cercle // Rotations des groupes et cercles ctx.save() ctx.translate(this.centreX, this.centreY) ctx.rotate(Math.PI/6) ctx.translate(-this.centreX, -this.centreY) this.print() ctx.restore()
Faculté I&C, Claude Petitpierre, André Maurer 23 Une hiérarchie de classes Transformation tPrint tTouch FormeGraph print Groupe print touch liste Cercle print touch
Faculté I&C, Claude Petitpierre, André Maurer 24 Sélection ( sans transformation ) // Curseur xc = event.clientX; yc = event.clientY // Dans le cercle (curseur – centre < r) this.touch = function(xc,yc) { if (Math.sqrt((xc-x)*(xc-x)+(yc-y)*(yc-y))<r) { elSelectionne = this return true } else { return false } }
Faculté I&C, Claude Petitpierre, André Maurer 25 Sélection ( sans transformation ) // Dans le groupe this.touch = function (xc,yc) { for (var i=0; i<this.liste.length;i++) { if (this.liste[i].touch(xc,yc)) { if (this!=groupeDeBase) { elSelectionne = this } return true } } return false }
Faculté I&C, Claude Petitpierre, André Maurer 26 Sélection avec transformation inverse Rotation Groupe Rotation Cercle clientX clientY xc,yc transformer -1 cercle.touch(xc,yc) Cercle // les transformations des coordonnées du curseur doivent être effectuées à // partir de la transformation de base! Rotation Groupe
Faculté I&C, Claude Petitpierre, André Maurer 27 Transformation inverse du curseur cos(a)sin(a)0 -sin(a)cos(a) y 01-x y01x00110y01x001 cos(a)sin(a)x -sin(a)cos(a)y y 01-x 001
Faculté I&C, Claude Petitpierre, André Maurer 28 Transformation inverse du curseur cos(a)sin(a)x -sin(a)cos(a)y y 01-x 001 [ [cosA, sinA, -this.xr*cosA-this.yr*sinA+this.xr], [-sinA, cosA, this.xr*sinA-this.yr*cosA+this.yr], [0,0,1] ] cos(a)sin(a) -x*cos(a)-y*sin(a)+x -sin(a)cos(a) x*sin(a)-y*cos(a)+y 0 01
Faculté I&C, Claude Petitpierre, André Maurer 29 tTouch dans la transformation xc = event.clientX; yc = event.clientY this.tTouch = function(xc,yc) { var cosA = Math.cos(this.angle) var sinA = Math.sin(this.angle) var xy= multV([ [cosA, sinA, -this.xr*cosA-this.yr*sinA+this.xr], [-sinA, cosA, this.xr*sinA-this.yr*cosA+this.yr], [0,0,1] ], [xc,yc,1]) return this.touch(xy[0],xy[1]) }
Faculté I&C, Claude Petitpierre, André Maurer 30 Sauvetage Créer un arbre sans les méthodes Sauver larbre au moyen de JSON dans un fichier Restauration Lire le fichier et retransformer le contenu en arbre au moyen de JSON Recréer larbre avec les méthodes en recréant les objets (new)
Faculté I&C, Claude Petitpierre, André Maurer 31 Création dobjets pour la sauvegarde ( constants, sans méthodes ) // Cercle this.save = function() { // objet avec les paramètres dun cercle return {x:x, y:y, r:r, xr:xr, yr:yr, angle:angle, strokeStyle:this.strokeStyle} } // Groupe this.save = function () { // un groupe contient une liste + qq paramètres var g = { liste: [], xr:xr, yr:yr, angle:angle } for (var i=0; i<this.liste.length;i++) { g.liste.push(this.liste[i].save()) } return g }
Faculté I&C, Claude Petitpierre, André Maurer 32 Restauration à partir des objets JSON // Groupe this.restore = function(o) { // o, el objets obtenu par JSON for (var i=0; i<o.liste.length;i++) { // this, groupe en construction var el = o.liste[i] if (el.liste) { // c'est un groupe var g = new Groupe(el.xr, el.yr, el.angle) this.liste.push(g) g.restore(el) } else if (el.r) { // c'est un cercle 1 var c = new Cercle(el.x, el.y, el.r, el.xr, el.yr, el.angle) c.strokeStyle = el.strokeStyle this.liste.push(c) } } // 1 on ne pas mettre cette instruction dans Cercle, } // car il faut le créer avant dappeler ses méthodes !
Faculté I&C, Claude Petitpierre, André Maurer 33 Transformation JSON dessin groupeDeBase méthodes racine JSON el this.liste.push( new Groupe(el…) ) new Cercle(el…) o
Faculté I&C, Claude Petitpierre, André Maurer 34 Objets JSON function save(filename) { var dessin = groupeDeBase.save() File.write(filename, JSON.stringify(dessin)) } function restore(filename) { var dessin = JSON.parse(File.read(filename)) groupeDeBase = new Groupe(0,0,0) groupeDeBase.restore(dessin) }