peterS.: Basisklasse und Vererbung

Beitrag lesen

gruss Jack,

den ausfuehrungen und links von molily in
  https://forum.selfhtml.org/?t=124977&m=805605
  moechte ich noch ein paar grundlegende ueberlegungen
  zu dem von Dir aufgeworfenen vererbungsfall anhand
  eines kommentierten beispiels und 2 moegliche loesungen,
  Dein beispiel betreffend, hinzufuegen.

ausserdem sei Dir die lektuere von Douglas Crockfords
  JavaScript-artikeln ans herz gelegt:

http://javascript.crockford.com/ - besonders die

zu Kapselung und Vererbung.

los gehts:

var BaseConstructor = function (/*any arguments*/) {  
  
  this.construcor = arguments.callee; /* ist identisch zu:  
  this.construcor = BaseConstructor; */  
  
/*  
  folgende eigenschaften und methoden lassen sich nur  
  innerhalb des funktionsrumpfes eines konstruktors  
  vereinbaren:  
*/  
  
//private eigenschaften:  
  var privateProperty1 = arguments[0];  
  var privateProperty2 = arguments[1];  
  
//private methoden:  
  var privateMethod1 = function (/*up to you*/) {/*your stuff*/};  
  var privateMethod2 = function (/*up to you*/) {/*your stuff*/};  
  
//oeffentliche privilegierte methoden:  
  
  /*setter: kontrollierter zugriff auf  
    private eigenschaften und methoden;  
  */  
  this.publicPrivilegedSetterMethod = function (/*any arguments*/) {  
    /*  
      assign this functions arguments to your private properties  
      or pass them over to your private methods;  
    */  
  };  
  
  /*getter: kontrollierte rueckgabe  
    privater eigenschaften und methoden;  
  */  
  this.publicPrivilegedGetterMethod = function () {  
    /*  
      return private stuff;  
    */  
  };  
  
/*  
  alle oeffentlichen nicht privilegierten methoden eines objekts  
  sollten sowiso als eigenschaften des prototypen-objekts seines  
  konstruktors vereinbart werden.  
  
  selbiges gilt fuer oeffentliche eigenschaften, die fuer alle  
  objekte einer objektfamilie gleich lauten und deren initialer  
  wert fuer alle objekte identisch ist.  
  
  im bsp. wird fuer den basis-konstruktor "Car" die anzahl der  
  raeder ohne umschweife wie folgt festgelegt:  
  
  var Car = function () {};  
  Car.prototype.amountOfWheels = 4;  
  
  konstruktoren spezieller fahrzeugmarken muessen sich nicht  
  mehr um diese eigenschaft kuemmern, wenn folgenden zeilen  
  beachtung geschenkt wurde:  
  
  var CarBrand = function () {};  
  CarBrand.prototype = new Car();  
  
  weiterhin kann man die deklarierung/initialisierung aller  
  oeffentlichen eigenschaften, die fuer die konstruktoren einer  
  objektfamilie gleich lauten in eine entsprechende oeffentliche  
  nicht privilegierte methode - z.b.: "compile" , "initialize" -  
  auslagern.  
*/  
  this.initialize.apply(this,arguments);  
};  
  
//methoden des objektprototypen (oeffentlich und nicht privilegiert):  
  
  BaseConstructor.prototype.initialize = function (/*any arguments*/) {  
  
  //oeffentliche eigenschaften:  
    this.publicProperty1 = arguments[2];  
    this.publicProperty2 = arguments[3];  
  };  
  
  
/*  
  konstruktor, dessen objekte auf objekten  
  des typs "baseconstructor" aufbauen sollen:  
*/  
var BaseEnhancer = function (/*any arguments*/) {  
  
  this.construcor = arguments.callee; /* identical to:  
  this.construcor = BaseEnhancer; */  
  
  var privateProperty1 = arguments[0];  
  var privateProperty2 = arguments[1];  
  
  var privateMethod1 = function (/*up to you*/) {/*your stuff*/};  
  var privateMethod2 = function (/*up to you*/) {/*your stuff*/};  
  
  this.publicPrivilegedSetterMethod = function (/*any arguments*/) {  
  //to exemplify  
    privateProperty1 = arguments[0];  
  };  
  this.publicPrivilegedGetterMethod = function () {  
  //to exemplify  
    return privateProperty1;  
  };  
  /*  
    an dieser stelle wird die methode "initialize" des  
    objektprototypen "BaseConstructor" im kontext von  
    "BaseEnhancer" ausgefuehrt.  
  */  
  this.initialize.apply(this,arguments);  
  /*  
    im gegebenen bsp. besaesse ein objekt vom typ  
    "baseenhancer" jetzt auch die oeffentlichen  
    eigenschaften "publicProperty1" sowie "publicProperty2".  
  */  
};  
BaseEnhancer.prototype = new BaseConstructor();  
  
  
//Dein ausgangscode - von mir kommentiert:  
  
  function EingabeElement(x,y) {  
  
  //oeffentliche eigenschaften:  
    this.x = x;  
    this.y = y;  
    this.elementId = 0;  
  
  //eine setter methode ist doch nur dann sinnvoll,  
  //wenn die entsprechend zu setzenden eigenschaften  
  //privat statt oeffentlich sind.  
    this.setX = function(sX) {  
      this.x = sX;  
    };  
  }  
  function Knopf(x,y,beschriftung) {  
  
   //Super-Konstruktor aufrufen  
   EingabeElement.call(this,x,y);  
  
   //Attribute  
   this.value = beschriftung;  
  
   return this; // kann man (muss man nicht) weglassen;  
  }  
  //Ableiten  
  Knopf.prototype = new EingabeElement();  
  
  
//umsetzung 1) alles oeffentlich:  
  
  var EingabeElement = function (x, y) {  
  
  //oeffentliche eigenschaften:  
    this.x = x;  
    this.y = y;  
  
    this.elementId = 0;  
  };  
  var Knopf = function (x, y, beschriftung) {  
  
  //"super-konstruktor" aufrufen:  
    EingabeElement.call(this,x,y); /* oder:  
    EingabeElement.apply(this,arguments); oder:  
    this.constructor.call(this,x,y); oder:  
    this.constructor.apply(this,arguments); */  
  
  //weitere oeffentliche eigenschaft:  
    this.value = beschriftung;  
  };  
  //ableiten:  
  Knopf.prototype = new EingabeElement();  
  
/*  
  bei dieser umsetzung gilt fuer jedes objekt vom typ "knopf":  
  
  ((knopfObject.constructor === EingabeElement) === true);  
  
  da dessen "constructor"-referenz vom objektprototypen -  
  einem objekt vom typ "eingabeelement" - ueberschrieben wird.  
  
  
  um direkte referenzen zu erhalten muss man anders vorgehen:  
*/  
  
//umsetzung 2) alles oeffentlich:  
  
  var EingabeElement = function (x, y) {  
  
    this.constructor = arguments.callee;  
    this.compile.apply(this,arguments);  
  };  
  EingabeElement.prototype.compile = function () {  
  
  //oeffentliche eigenschaften:  
    this.x = arguments[0];  
    this.y = arguments[1];  
  
    this.elementId = 0;  
  };  
  var Knopf = function (x, y, beschriftung) {  
  
    this.constructor = arguments.callee;  
  
  //super-konstruktion im kontext von "Knopf":  
    this.compile.apply(this,arguments);  
  
  //weitere oeffentliche eigenschaft:  
    this.value = beschriftung; /* oder  
    this.value = arguments[2]; */  
  };  
  //ableiten:  
  Knopf.prototype = new EingabeElement();  
  
/*  
  fuer umsetzung 2) gilt fuer jedes objekt vom typ "knopf":  
  
  ((knopfObject.constructor === Knopf) === true);  
*/  
  
/*umsetzung 3) private eigenschaften und setter/getter:  
  
  da private eigenschaften/methoden sowie deren getter- bzw.  
  setter-methoden unmittelbar im funktionsrumpf eines  
  konstruktors notiert werden muessen, ist es um vererbungs-  
  muster schlecht bestellt.  
  
  im gegebenen bsp. findet vererbung ueberhaupt nicht statt,  
  da keinerlei eigenschaften und methoden existieren, die  
  den weg in die prototypenkette nehmen koennten.  
*/  
  var EingabeElement = function (newX, newY) {  
  
    var x = newX;  
    var y = newY;  
    var elementId = 0;  
  
    this.setX = function (newX) {  
      x = newX;  
    };  
    this.setY = function (newY) {  
      y = newY;  
    };  
    this.setElementId = function (newId) {  
      elementId = newId;  
    };  
    this.getX = function () {return x;};  
    this.getY = function () {return y;};  
    this.getElementId = function () {return elementId;};  
  };  
  var Knopf = function (newX, newY, beschriftung) {  
  
    var x = newX;  
    var y = newY;  
    var elementId = 0;  
  
  //eine oeffentliche eigenschaft:  
    this.value = beschriftung;  
  
    this.setX = function (newX) {  
      x = newX;  
    };  
    this.setY = function (newY) {  
      y = newY;  
    };  
    this.setElementId = function (newId) {  
      elementId = newId;  
    };  
    this.getX = function () {return x;};  
    this.getY = function () {return y;};  
    this.getElementId = function () {return elementId;};  
  };

so long - peterS. - pseliger@gmx.net

--
"Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive." - Douglas Crockford
ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]