Objektorientierung in JavaScript/Datenkapselung, Vererbung, Polymorphie/Vererbung

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Javascript</language>
==Das Klonen von Objekten==

Ein Prototyp dient als Vorlage für neue Objekte. Jedes bereits vorhandene Objekt kann ein Prototyp sein. Die neuen Objekte erhalten alle Eigenschaften und Methoden ihres Prototypen: Sie ''erben'' diese.
In JavaScript können Objekte mit der Anweisung <tt>Object.Create(prototype)</tt> erzeugt werden.

<code id="542717510qff3042016">
var altmetall = {
  masseInKg: 20,
  form : "Quader"
};
var neumetall = Object.create(altmetall);
neumetall.form = "Zylinder";
</code>
<run id="542717e5403042016">
neumetall.masseInKg;
</run>
Das neue Objekt hat die gleiche Masse wie das Altmetall, aber es hat eine andere Form. Objekte können die Eigenschaften und Funktionen ihrer Prototypen ändern oder neue hinzufügen.
Die Eigenschaft <tt>masseInKg</tt> des Objekts <tt>neumetall</tt> referenziert (verweist auf) die Eigenschaft von<tt>altmetall</tt>. Das heißt, es speichert den Wert der Variablen nicht selbst, sondern leitet den Aufruf an den Prototypen weiter.
<code id="5427181003042016">
altmetall.masseInKg= 50;
</code>
<run id="5426181003042016g">
neumetall.masseInKg;
</run>
Der Wert einer Eigenschaft eines Objekts ändert sich, wenn sich der Wert des Prototypen ändert.

Ob ein Objekt eine eigene Eigenschaft besitzt oder diese durch seinen Prototypen erlangt, kann man durch <tt>hasOwnProperty("property")</tt> überprüfen, welche alle Objekte von <tt>Object</tt> erben.

<run id="5427181403042016">
neumetall.hasOwnProperty("masseInKg") + "\n" + neumetall.hasOwnProperty("form");
//Masse wird geerbt, Form wird geändert
</run>

==Vererbung zwischen Klassen==
Durch die Vererbung zwischen Klassen können ''spezifische Klassen'' von ''allgemeinen Klassen'' abgeleitet werden. Es ist damit möglich, Klassenhierarchien zu konstruieren, in denen eine allgemeine Klasse (z.B. <tt>Lebewesen</tt>) immer weiter spezifiziert wird, bis man zu konkreten Ausprägungen wie dem <tt>LoxodontaAfricana</tt> kommt. In der allgemeinen Klasse können Methoden definiert werden, die alle Lebewesen haben, beispielsweise <tt>vererben()</tt> oder <tt>wachsen()</tt>. In einer ''Unterklasse'' von <tt>Lebewesen</tt> können dann die Merkmale von Säugetieren spezifiziert werden. In der ''konkreten Klasse'' <tt>HomoSapiens</tt> werden dann letztendlich die Merkmale und Funktionen eines Menschen beschrieben.
Die vererbende Klasse nennt man ''Ober-, Basis- oder Superklasse'', die erbende ''Unter- oder Subklasse''.

===JavaScript===
Damit Klassen voneinander erben, muss die Eigenschaft <tt>prototype</tt> der Klasse ein Objekt der Oberklasse referenzieren.
<code id="5427182903042016">
function Lebewesen() {
  this.reizbarkeit = true;
  this.stoffUndEnergiewechsel = function() {
    return "Stoff- und Energiewechsel";
  };
}
function Saeugetier() {
  this.wirbelsaeule = true;
}
Saeugetier.prototype = new Lebewesen();
function Mensch(vorname, nachname, alter) {
  this.vorname = vorname;
  this.nachname = nachname;
  this.alter = alter;
  this.sprechen = function(aussage) {
    return aussage;
  };
}
Mensch.prototype = new Saeugetier();
</code>
<run id="5426184003042016">
var peter = new Mensch("Peter", "Maier", 54);
(peter.reizbarkeit + "\n" +
 peter.wirbelsaeule + "\n" +
 peter.vorname)
</run>
<tt>Peter</tt> kann Eigenschaften und Funktionen der Klassen <tt>Lebewesen</tt>, <tt>Säugetier</tt> und <tt>Mensch</tt> aufrufen. Er ist ein Objekt von all diesen Klassen.

Möchte man jetzt noch eine Klasse <tt>Person</tt> erstellen, kann diese von <tt>Mensch</tt> erben. <tt>Mensch</tt> hat aber einen parametrisierten Konstruktor. Damit die Klasse <tt>Person</tt> die Variablen, die auch die Oberklasse besitzt, nicht selbst speichern muss, werden diese an die Oberklasse übergeben.
<code id="542703041838h">
function Person(vorname, nachname, alter, steuerID) {
  this.steuerID = steuerID;
}
Person.prototype = new Mensch(vorname, nachname, alter);
</code>
So nicht, sondern so;

<code id="5427030420161840uh">
function Person(vorname, nachname, alter, steuerID) {
  Mensch.call(this, vorname, nachname, alter);
  this.steuerID = steuerID;
}
</code>
Die <tt>call</tt>-Methode der Oberklasse wird mit <tt>this</tt> sowie allen zu übergebenden Parametern aufgerufen. Danach sind die Werte in der Klasse <tt>Mensch</tt> gespeichert.
<run id="5427185203042016">
var p = new Person("Max", "Mustermann", 33, "1232452678");
p.hasOwnProperty("vorname");
</run>