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
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:]
"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:]