HighDots Forums  

Vererbung in Javascript

Javascript (German) Programmiersprache JavaScript. (de.comp.lang.javascript)


Discuss Vererbung in Javascript in the Javascript (German) forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Norbert Trunk
 
Posts: n/a

Default Vererbung in Javascript - 02-20-2007 , 04:10 AM






Hallo zusammen,

ich arbeite mich seit einigen Tagen in Javascript ein und experimentiere
nun mit Objekten. Etwas verwirrend ist für mich das Vererbungskonzept mit
prototype.

Im folgendem Script:

// Beginn Constructor-Test

function StopConstructorA(){}

function ObjectA(param_a){
if (param_a == StopConstructor) return;
alert("construct ObjectA: " + param_a);
this.prop_a = param_a;
}

function ObjectB(param_a, param_b){
alert("construct ObjectB: " + param_a + "," + param_b);
this.constructor(param_a);
this.prop_b = param_b;
}
ObjectB.prototype = new ObjectA(StopConstructorA);

function test(){
b1 = new ObjectB('testparam_a1', 'testparam_b1');
b2 = new ObjectB('testparam_a2', 'testparam_b2');
}

// Ende Constructor-Test

wird ja der Konstruktor von ObjectA 3x ausgeführt. Deshalb breche ich mit
Hilfe von StopConstructor ObjectA beim Aufruf aus der prototype-Zuweisung
ab.

Ist das so üblich, oder gibt es bessere Möglichkeiten (vorzugsweise eine,
die ObjectA ausschliesslich aus einer Instanz von ObjectB aufruft)?
Zweite Frage: Gibt es eine Möglichkeit der Mehrfachvererbung (z.B. ObjectC
hat als prototyp ObjectB *und* ObjectA)?

Gruß
Norbert

Reply With Quote
  #2  
Old   
J. Strübig
 
Posts: n/a

Default Re: Vererbung in Javascript - 02-20-2007 , 06:25 AM






Norbert Trunk schrieb:
Quote:
Hallo zusammen,

ich arbeite mich seit einigen Tagen in Javascript ein und experimentiere
nun mit Objekten. Etwas verwirrend ist für mich das Vererbungskonzept
mit prototype.
ist es auch.

Quote:
Im folgendem Script:
Läuft bei mir nicht:
Fehler: StopConstructor is not defined
Quelldatei: ..../test.html
Zeile: 9


Quote:
wird ja der Konstruktor von ObjectA 3x ausgeführt.
nein, wird nur einmal ausgeführt und zwar bei der Zuweisung des prototypen.

Quote:
Ist das so üblich, oder gibt es bessere Möglichkeiten (vorzugsweise
eine, die ObjectA ausschliesslich aus einer Instanz von ObjectB aufruft)?
Das verstehe ich nicht ganz.
Aber es ist üblich über prototype zu vererben.

Allgemein zum Thema JS, OOP, Vererbung kann ich dir diese drei Seiten
empfehlen:
http://www.crockford.com/javascript/inheritance.html
http://www.cs.rit.edu/~atk/JavaScript/manuals/jsobj/
http://phrogz.net/JS/Classes/OOPinJS.html


Quote:
Zweite Frage: Gibt es eine Möglichkeit der Mehrfachvererbung (z.B.
ObjectC hat als prototyp ObjectB *und* ObjectA)?

nein.

Struppi.


Reply With Quote
  #3  
Old   
Norbert Trunk
 
Posts: n/a

Default Re: Vererbung in Javascript - 02-20-2007 , 08:46 AM



J. Strübig schrieb:

Quote:
experimentiere nun mit Objekten. Etwas verwirrend ist für mich das
Vererbungskonzept mit prototype.

ist es auch.
Da bin ich ja beruhigt, ich dachte schon, es liegt an mir...

Quote:
Läuft bei mir nicht:
Fehler: StopConstructor is not defined
Quelldatei: ..../test.html
Zeile: 9
Stimmt, da habe ich nach dem "..uctor" ein A vergessen.

Quote:
wird ja der Konstruktor von ObjectA 3x ausgeführt.

nein, wird nur einmal ausgeführt und zwar bei der Zuweisung des
prototypen.
Er wird im Konstruktor von ObjectB explizit aufgerufen, bei 2 Instanzen
(ist das in Javascript der richtige Ausdruck?) macht das zusammen mit dem
Aufruf bei der Zuweisung 3x.
Sinn dieser Konstruktion ist es, dem ObjectB die zur Initialisierung von
ObjectA nötigen Werte mitzuteilen, und dann ObjectA seine eigene
Initialisierung durchführen zu lassen.

Quote:
Ist das so üblich, oder gibt es bessere Möglichkeiten (vorzugsweise
eine, die ObjectA ausschliesslich aus einer Instanz von ObjectB
aufruft)?

Das verstehe ich nicht ganz.
Na ja, den ersten Konstruktoraufruf über einen Kontrollparameter zu
blocken scheint mir, sagen wir mal, unelegant. Besser wäre es, diesen ganz
zu vermeiden.

Quote:
Aber es ist üblich über prototype zu vererben.
Wenn es nicht anders geht, kann ich damit auch leben (ansonsten hätte ich
wohl ein Problem ;-)

Vielen Dank, werde ich mir zu Gemüte führen.

Quote:
Zweite Frage: Gibt es eine Möglichkeit der Mehrfachvererbung (z.B.
ObjectC hat als prototyp ObjectB *und* ObjectA)?

nein.
Das /ist/ schade.

Gruß
Norbert


Reply With Quote
  #4  
Old   
wolfgang zeidler
 
Posts: n/a

Default 2 Antworten zu : Vererbung in Javascript - 02-20-2007 , 02:31 PM



Norbert Trunk wrote:
Quote:
Hallo zusammen,
[ ... ]
Zweite Frage: Gibt es eine Möglichkeit der Mehrfachvererbung (z.B.
ObjectC hat als prototyp ObjectB *und* ObjectA)?
NEIN:
*Über* *prototype* ist nur Einfachvererbung möglich.

JA:
Wenn du die Vererbung "per Hand" machst,
der Kind-Konstruktor greift sich alle Eltern-Konstruktoren
als Methode und führt sie aus.

BEISPIEL:
<script>
function buntes_ding ( farbe ) {
this.farbe = farbe
this.farb_info = function () { alert ( this.farbe ) }
}
function runde_sache () {
this.form_info = 'rund'
}
function bunt_und_rund ( farbe ) {
this.hugo = buntes_ding
this.hugo ( farbe )
this.hugo = runde_sache
this.hugo ()
this.wert = 4711
}
var demo = new bunt_und_rund ( 'grün' )
demo.farb_info ()
alert ( demo.form_info )
alert ( demo.wert )
</script>

mfG., wz

--
http:\wzwz.de\mail


Reply With Quote
  #5  
Old   
Norbert Trunk
 
Posts: n/a

Default Re: 2 Antworten zu : Vererbung in Javascript - 02-21-2007 , 07:51 AM



wolfgang zeidler schrieb:

Quote:
Zweite Frage: Gibt es eine Möglichkeit der Mehrfachvererbung (z.B.
ObjectC hat als prototyp ObjectB *und* ObjectA)?

NEIN:
*Über* *prototype* ist nur Einfachvererbung möglich.

JA:
Wenn du die Vererbung "per Hand" machst,
der Kind-Konstruktor greift sich alle Eltern-Konstruktoren
als Methode und führt sie aus.
[Beispiel gesnippt]

!, ! und nochmals !
Das ist ja ein Ding! Sieht so aus, als müsste ich meine gewohnten
Vorstellungen auseinandernehmen, gegen den Strich bürsten und dann wieder
verknoten.
Jetzt wo ich es sehe ist natürlich logisch, weil der Konstruktor auch eine
Funktion ist. Ich glaube aber nicht, dass ich da so schnell oder auch
überhaupt von selbst drauf gekommen wäre.

Inzwischen habe ich u.a. die Dokumentation der prototype-library gelesen,
da wird (wenn ich das richtig verstanden habe) Mehrfachvererbung über eine
implements-Methode realisiert, die alle Properties und Methods einer
Klasse in die Zielklasse kopiert. Die obige Art und Weise ist da aber
wesentlich einfacher.

Irgendwo im Quelltext muss ich die Vererbungsbeziehung niederschreiben, ob
jetzt über class.prototype, per implements-Methode oder so wie im Beispiel
ist ja zunächst mal egal. Gibt es im instanzierten Objekt einen
feststellbaren Unterschied zur Vererbung per prototype?

Gruß
Norbert


Reply With Quote
  #6  
Old   
Georg Maaß
 
Posts: n/a

Default Re: Vererbung in Javascript - 02-21-2007 , 05:00 PM



Norbert Trunk wrote:

Quote:
Hallo zusammen,

ich arbeite mich seit einigen Tagen in Javascript ein und
experimentiere nun mit Objekten. Etwas verwirrend ist für mich das
Vererbungskonzept mit prototype.
Daran ist nichts verwirrend, weil es das nämlich nicht gibt.

Prototypen dienen zur gemeinsamen LESE-Nutzung von Eigenschaften. Das
ist keine Vererbung. Solange nur LESE-Zugriff erfolgt, existiert die
Eigenschaft nur in der Ausprägung des Prototypen. Bei Schreibzugriff
wird ein eigenes Exemplar angelegt.

function A()
{
this.banana='groß';
}

function B()
{
}

B.prototype = new A;

a = new A;
b = new B;
c = new B;

alert(a.banana+'\n'+b.banana+'\n'+c.banana);

Das sollte folgendes ausgeben:
groß
groß
groß

Das erste "groß" ist von a.banana, die anderen beiden sind von
B.prototype.banana.

b.banana='klein';

alert(a.banana+'\n'+b.banana+'\n'+c.banana);

Das sollte folgendes ausgeben:
groß
klein
groß

Das erste "groß" ist von a.banana, das "klein" ist von dem nun neu
angelegeten b.banana, das letzte "groß" ist wieder von B.prototype.banana.

a.banana='mittel';

alert(a.banana+'\n'+b.banana+'\n'+c.banana);


Das sollte folgendes ausgeben:
mittel
klein
groß

Das "mittel" ist von a.banana, das "klein" ist von b.banana, das "groß"
ist wieder von B.prototype.banana.


Ich hoffe, daß dies nun etwas klarer ist. Das ist KEIN
VERERBUNGSMECHANISMUS, sondern Resourcen-Sharing-Mechanismus mit
Create-Individual-On-Write Mechanismus im Hintergrund. Deshalb sind
Setter-Funktionalitäten im Prototypen sinnlos, weil ein Setter auf
B.prototype.banana bei einer Zuweisung an b.banana nicht angesprochen
wird, sondern statt dessen eine eigene Eigenschaft b.banana angelegt
wird, welche einen eventuellen Setter des Prototypen in b verdeckt.


Quote:
Zweite Frage: Gibt es eine Möglichkeit der Mehrfachvererbung (z.B.
ObjectC hat als prototyp ObjectB *und* ObjectA)?
Nein, denn erstesn gibt es ohenhin keine Vererbung und zweitens ist die
Prototype-Chain eine lineare Kette und kein Baum.

Für echte Vererbung (allerdings keine Mehrfach-Vererbung) muß Du auf
JavaScript 2.0 warten. Dort gibt es dann auch Klassen, diese bieten dann
einen Vererbungsmechanismus.


Reply With Quote
  #7  
Old   
Georg Maaß
 
Posts: n/a

Default Re: Vererbung in Javascript - 02-21-2007 , 05:35 PM



Norbert Trunk wrote:

Quote:
J. Strübig schrieb:

experimentiere nun mit Objekten. Etwas verwirrend ist für mich das
Vererbungskonzept mit prototype.


ist es auch.


Da bin ich ja beruhigt, ich dachte schon, es liegt an mir...

Läuft bei mir nicht:
Fehler: StopConstructor is not defined
Quelldatei: ..../test.html
Zeile: 9


Stimmt, da habe ich nach dem "..uctor" ein A vergessen.

wird ja der Konstruktor von ObjectA 3x ausgeführt.


nein, wird nur einmal ausgeführt und zwar bei der Zuweisung des
prototypen.


Er wird im Konstruktor von ObjectB explizit aufgerufen
Nein, das wird es nicht.

Wenn Du das meinst:

Quote:
this.constructor(param_a);
Das ruft Function auf und erzeugt wahrscheinlich ein gleich wieder in
der GarbageCollection landendes Funktions-Objekt:

function(){}

Quote:
Sinn dieser Konstruktion ist es, dem ObjectB die zur Initialisierung
von ObjectA nötigen Werte mitzuteilen, und dann ObjectA seine eigene
Initialisierung durchführen zu lassen.
Das ist Unsinn, der von der Vorstellung, daß es sich um Vererbung
handle. Das ist aber keine Vererbung, sondern lediglich ein sehr
effizienter Mechanismus um z.B. Methoden, die ja normalerweise nicht
verändert werden, gemeinsam zu nutzen und so Speicherplatz zu sparen,
den jede Methode ist ein Objekt, das Ressourcen verbraucht.

Auch Andere Container-Objekte kann man so gemeinsam nutzen um Ressourcen
zu sparen.

Die ursprüngliche Idee und daher auch Namens gebend ist, daß man ein
Muster-Exemplar anlegt mit lauter Default-Werten und dann die
Arbeistinstanzen mit dem Defaultwerten des Muster-Exemplars vorbelegt,
ohne jede einzelne Eigenschaft kopieren zu müssen.

function MusterApfel()
{
this.durchmesser=30;
this.farbe='rot';
this.geschmack='sauer';
}

function Apfel()
{
}
Apfel.prototype=new MusterApfel;

a = new Apfel;

a sieht nun aus wie ein MusterApfel.

b = new Apfel;
b.farbe='gelb';

b unterschiedet sich von a nur durch die gelbe Farbe.

Jetzt willst Du alle Äpfel auch die schon existierenden Instanzen altern
lassen:

Apfel.prototype.farbe='braun';

Werden wirklich alle Äpfel braun?

Nein, nur a wird braun, weil a keine eigene Farbe hat, sondern die Farbe
des Prototypen. b bleibt gelb, weil b im Unterschied zu a bei unserer
Zuweisung eine eigene Farbe bekommen hat.

So sieht das eigentliche Verwendungskonzept von prototype aus, und
deshalb heißt es auch so. Es ist ein Prototyp, keine Vererbung.

Quote:
Wenn es nicht anders geht, kann ich damit auch leben (ansonsten hätte
ich wohl ein Problem ;-)
Ja, das hast Du, weil es viele Idioten gibt, die von Vererbung sprechen,
obwohl es kein Vererbung ist. Für manche Zwecke ist der prototyp viel
besser geeignet als Vererbung, für andere Zwecke ist Vererbung besser
geeignet als der Prototyp. Ab JavaScript 2.0 werden wir beides neben
einander haben.

Das hier ist die Trick-Kiste; begrifflich ist da vieles falsch.
Konstruktoren liefern grundsätzlich keinen Rückgabewert. Eine Funktion,
die einen liefert, ist gegebenenfalls eine Factory aber kein Konstruktor.

Das scheint mir eine Kopie der alten Netscape-Doku zu sein, die mit
ihrem Verglaich von Java und JavaScript bei gleicher Begrifflichkeit
aber völlig unterschiedlichen Konzepten die Verwirrung überhaupt erst in
die Welt gesetzt hat. Ah ja, unten sehe ich es ja auch: Verbrochen 1997
von Netscape.

Es ist einfach keine Vererbung. Der Begriff prototype ist sehr viel
treffender als inheritance. Es ist keine Vererbung, sondern es sind
read-only shared objects zum Zwecke der Vorbelegung nach dem Muster
eines Prototypen.

Herzliche Grüße, Georg


Reply With Quote
  #8  
Old   
Norbert Trunk
 
Posts: n/a

Default Re: Vererbung in Javascript - 02-22-2007 , 09:29 AM



Georg Maaß schrieb:

Quote:
Wenn Du das meinst:

this.constructor(param_a);
Ja das habe ich gemeint.

Quote:
Das ruft Function auf und erzeugt wahrscheinlich ein gleich wieder in
der GarbageCollection landendes Funktions-Objekt:
[...eine Menge erhellender Erläuterungen...]

Vielen Dank, das war hochinteressant und hilft mir wesentlich weiter beim
Verständnis der entsprechenden Konzepte.

Gruß
Norbert



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.