Klassen und Objekte
warn> Es wird vorausgesetzt, dass du schon vom KAOM-Modell gehört hast. Falls nicht frage deinen Lehrer oder beiße dich trotzdem durch.
Motivation
Bisher haben wir bei einfachen Objekten gesehen, dass wir Variabeln gemeinsam speichern können, um ein wenig mehr Übersicht in unser Programm zu bringen:
var rechteck = {breite:10, hoehe:20};
Sehr schön. Den Flächeninhalt zu berechnen ist also einfach:
var flaeche = rechteck.breite * rechteck.hoehe
In diesem Beispiel ganz einfach. Möchten wir etwa das Volumen eines Tigers ausrechnen, wäre die Berechnung vermutlich viel komplexer. Auch möchten wir das vielleicht mehrfach berechnen. Uns rettet eine Funktion:
var rechteck = {breite:10, hoehe:20};
var flaeche = berechneFlaeche(rechteck.hoehe, rechteck.breite);
berechneFlaeche(hoehe, breite) {
return hoehe * breite;
}
Super. Jetzt müssen wir nur noch das einfache Objekt und die Funktion zusammen in unser Programm übernehmen und schon können wir starten. Das ist für kleine Programme okay, aber bei großen sehr aufwendig. Ein Trick ist es jetzt, die Funktion auch einfach als Variable zu speichern. Hö? Ja, genau. Wir speichern die Funktion als Variable:
var rechteck = {
breite:10,
hoehe:20,
berechneFlaeche: function (breite, hoehe) {
return hoehe * breite
}
};
var flaeche = rechteck.berechneFlaeche(rechteck.hoehe, rechteck.breite);
Das funktioniert, ist aber nicht so unendlich schön. Wir müssen ja die eigentlich schon definierten Variablen nochmals als Parameter übergeben. Würde man auf breite
zugreifen, würde man diese Variable nicht finden, da diese nicht innerhalb der Variable rechteck
sondern im Programm suchen würden. Wir müssten rechteck.breite
eingeben, um die Variable zu erhalten:
var rechteck = {
breite:10,
hoehe:20,
berechneFlaeche: function () {
return rechteck.hoehe * rechteck.breite
}
};
var flaeche = rechteck.berechneFlaeche();
Für ein Rechteck klappt das schon gut. Aber, wenn wir viele Rechtecke erstellen wollen, wird das sehr schwierig, da wir ja etwa den Namen rechteck
fest vorgegeben haben.
Klassen und Objekte
Aus diesem Grund erstellen wir eine sogenannte Klasse. Hier können wir alle notwendigen Variabeln und Funktionen vorab beschreiben und anschließend in einem sogenannten Objekt belegen:
class Rechteck {
constructor(breite, hoehe) {
this.hoehe = hoehe;
this.breite = breite;
}
berechneFlaeche() {
return this.hoehe * this.breite;
}
}
var rechteck1 = new Rechteck(10, 20);
var rechteck2 = new Rechteck(40, 20);
var flaeche1 = rechteck1.flaeche; // 200
var flaeche2 = rechteck2.flaeche; // 800
console.log(rechteck1.breite) //10 - funktioniert natürlich weiterhin
Im constructor
erstellen wir alle Variablen, welche wir innerhalb des Objektes später benötigen. Da wir noch nicht wissen, wie das Objekt später heißen wird, nennen wir es einfach this
. Mit new
erzeugen wir ein Objekt, womit wir dann arbeiten können.
Hier ist unsere Klasse Rechteck
noch ein wenig ausgefallener:
class Rechteck {
constructor(breite, hoehe) {
this.hoehe = hoehe;
this.breite = breite;
}
get flaeche() {
return this.berechneFlaeche();
}
berechneFlaeche() {
return this.hoehe * this.breite;
}
}
var rechteck = new Rechteck(10, 20);
var flaeche = rechteck.flaeche; //oder auch rechteck.berechneFlaeche()
Da man die Fläche ja auch als Attribut eines Objektes verstehen kann, welches zwar dazugehört, aber nicht extra angegeben werden sollte können wir get flaeche()
sagen. Von außen scheint es, als ob wir ein Attribut des Objektes aufrufen rechteck.flaeche
. Tatsächlich können wir hier aber nur einen Wert erhalten und nichts hineinschreiben.
Erben
Keine Sorge. Hier muss niemand sterben. Es kann aber manchmal extrem praktisch sein, sich etwas bei seinen Eltern abzuschauen. So wäre es denkbar eine Klasse Human
zu implementieren, die schon einen Vor- und Zunamen als Attribute hat und daraus den vollen Namen bildet. Nun ist es viel einfacher eine Klasse Student
zu erstellen, welche zusätzlich aufgrund objektiver Krieterien eine Note vergeben kann:
class Human {
constructor(forename, name) {
this.name = name;
this.forename = forename;
}
get fullName() {
return this.forename + " " + this.name;
}
}
class Student extends Human {
constructor(forename, name, email) {
super(forename, name);
this.email = email;
}
grade() {
return Math.round(Math.random() * 15) + 1;
}
}
var student = new Student("Osrun", "Krüger", "osrund@krüger42.test");
console.log(student.email);
console.log(student.fullName);