• Home
  • |
  • Blog
  • |
  • Java Tutorial #22 – Der Java Konstruktor

Java Tutorial #22 – Der Java Konstruktor

Zuletzt aktualisiert: September 4, 2024

In diesem Blogartikel werde ich dir erklären, was der Java Konstruktor ist, wie er funktioniert und wie man diesen anschließend in der Praxis selbst definieren kann.

Inhaltsverzeichnis

1. Was ist ein Java Konstruktor?

Der Konstruktor ist immer die erste Methode, die beim Instanziieren eines Objekts aufgerufen wird. Das Wort „immer“ habe ich absichtlich fett und kursiv dargestellt, weil es wichtig zu verstehen ist, dass es beim Instanziieren eines Objekts immer einen Konstruktor gibt.

An dieser Stelle fragst du dich wahrscheinlich, warum wir beim Erstellen von Instanzen von Objekten bisher noch nichts von einem Konstruktor gehört haben. Diese Frage ist auch vollkommen berechtigt.

Es gibt einen Standard-Konstruktor, den das Programm immer dann aufruft, wenn man nicht selbst einen eigenen Konstruktor definiert hat. Was man genau darunter versteht, werden wir uns gleich noch in der Praxis ansehen.

2. Wofür braucht man einen Konstruktor?

Der Java Konstruktor wird meistens dazu verwendet, um Attribute zu initialisieren. Wenn wir also ein Objekt instanziieren möchten, gehört dazu eine Klasse, die gewisse Attribute dieses Objekts vorgibt.

Dabei ist es sinnvoll, den Attributen schon zu Beginn, also beim Erstellen einer Instanz, Werte zuzuweisen. Dadurch müssen wir nämlich nicht erst das Objekt erstellen und anschließend mit den Set-Methoden alle Werte einzeln setzen, was sich ziemlich aufwendig gestaltet.

Mithilfe des Konstruktors lässt sich das Ganze beschleunigen. Das bedeutet so gesehen, dass der Konstruktor ein Objekt vorbereitet. Die Aufgabe des Konstruktors ist also, wie der Name schon verrät, Objekte zu konstruieren.

Damit sorgt die spezielle Konstruktor-Methode dafür, dass ein Objekt konstruiert wird. Wie bereits erwähnt, hat jede Klasse einen Konstruktor.

Um das Ganze nun mal in der Praxis zu verdeutlichen, bewegen wir uns direkt in die Entwicklungsumgebung.

3. Der Java Konstruktor in der Praxis

Auf der folgenden Abbildung kannst du das Beispiel erkennen, das wir in den Beiträgen zuvor aufgebaut hatten:

Das Beispiel, das wir in den vorherigen Artikeln aufgebaut haben

Wir sehen darauf die Klasse Car, von der wir eine Instanz erstellt haben. Die drei Zeilen darunter können wir vorerst löschen. Den Fokus werden wir nämlich erst mal auf die Instanziierung des Objekts legen.

Wie wir sehen, haben wir zunächst eine Variable vom Typ Car erstellt und diese car1 genannt. Anschließend kam der new-Operator zum Einsatz, den wir immer beim Erzeugen von Objekten verwenden. Danach haben wir die Methode Car() aufgerufen.

Dass wir es dabei mit einer Methode zu tun haben, lässt sich an den Klammern erkennen, die typisch für Methodenaufrufe sind. Genauer gesagt handelt es sich hierbei tatsächlich um den Konstruktoraufruf.

Wir rufen also mit dem Namen der Klasse gefolgt von einem Klammerpaar den Konstruktor der Klasse Car auf. Dadurch wird das ganze Objekt einmal konstruiert.

Wenn wir ein Objekt erzeugen, besitzt dieses alle Attribute, die allerdings nicht jeweils mit einem Wert vorbelegt sind. Das liegt daran, dass wir einen Standard-Konstruktor aufgerufen haben.

Wie ich bereits erwähnt habe, besitzt jede Klasse automatisch einen Konstruktor.

Der Standard-Konstruktor

Definiert man keinen Konstruktor, dann existiert lediglich der Standard-Konstruktor. Dieser sieht im Prinzip folgendermaßen aus:

public Car() {

}

Man beginnt mit einem Sichtbarkeitsmodifizierer, der beim Standard-Konstruktor public ist. Danach folgt der Name der Klasse und ein rundes Klammerpaar. Darunter setzt man einen Codeblock.

Da es sich um den Standard-Konstruktor handelt, wird in diesem nichts ausgeführt.

Wir haben damit den Standard-Konstruktor einmal explizit definiert. Beim Ausführen des Programms bleibt noch alles beim Alten und wir sehen natürlich nichts.

Der Grund, weshalb keine Änderung eingetreten ist, ist der, dass das Programm den Konstruktor ohnehin aufruft, wenn man keinen eigenen definiert.

Vorhin habe ich erwähnt, dass man einen Konstruktor dazu verwendet, um beispielsweise Attribute mit Werten vorzubelegen. Genau das werden wir jetzt einmal tun.

Mithilfe des Konstruktors Werte vorbelegen

Das bedeutet, wir können in den Klammern Parameter übergeben, so wie wir es bereits von den Methoden kennen.

Dafür wählen wir einen Parameter vom Typ String mit dem Namen color, einen weiteren Parameter vom Typ String namens brand und einen Parameter vom Typ Integer namens horsePower:

public Car(String color, String brand, int horsePower) {

}

In den Codeblock schreiben wir folgendes:

public Car(String color, String brand, int horsePower) {
         color = color;
         brand = brand;
         horsePower = horsePower;
}

Damit rufen wir den Konstruktor auf und übergeben direkt beim Aufruf, der in der Main-Methode stattfindet, die entsprechenden Parameter zwischen den Klammern:

Wir rufen den Java Konstruktor auf

Die Attribute des Objekts werden dann mit den Werten, die wir übergeben, vorbelegt.

Was jetzt allerdings etwas merkwürdig aussieht ist, dass sowohl das Attribut als auch der Parameter „color“ heißen und wir die Zeile „color = color“ schreiben:

Attribute und Parameter haben den gleichen Namen

Hier stellt sich die Frage, woher der Computer wissen soll, worauf wir uns beziehen. Meinen wir das Attribut oder doch den Parameter? Fest steht: Der Computer kann die beiden Wörter auf diese Weise tatsächlich nicht unterscheiden.

Aus diesem Grund müssen wir das erste „color“ so kennzeichnen, dass er weiß, dass es sich dabei um das Attribut des Objekts handelt.

Das setzt man in Java mit dem Schlüsselwort this um.

Das Schlüsselwort this

Mit this erstellen wir eine Referenz auf das Objekt selbst. Das heißt, dass wir uns mit diesem Schlüsselwort auf das Objekt beziehen, das den Konstruktor aufruft.

Nach dem this folgt ein Punkt und anschließend das Attribut color:

public Car(String color, String brand, int horsePower) {
         this.color = color;
         brand = brand;
         horsePower = horsePower;
}

Damit ist dem Computer klar: Mit dem Aufruf this.color ist das Attribut gemeint, wohingegen das Wort color hinter dem =-Zeichen den Parameter darstellt, der uns übergeben wird. Das sieht man bei Konstruktoren immer.

Wir können also auch noch vor den Attributen brand und horsePower das Schlüsselwort ergänzen:

public Car(String color, String brand, int horsePower) {
         this.color = color;
         this.brand = brand;
         this.horsePower = horsePower;
}

Bei gewöhnlichen Methoden setzen wir das im Übrigen genauso um. Das heißt, wenn wir bei Methoden Parameter übergeben, die die gleichen Namen wie die Attribute besitzen, können wir auch dort mit this arbeiten. So haben wir die Möglichkeit, dem Computer verständlich zu kommunizieren, was zu tun ist.

Die Fehlermeldung "The constructor is undefined"

Wenn wir jetzt das Ganze speichern und uns zurück ins Programm begeben, werden wir auch schon direkt von einer Fehlermeldung begrüßt:

Die Fehlermeldung sagt, dass der Java Konstruktor Car() nicht definiert ist

„The constructor Car() is undefined“.

Woran liegt das, wenn es vorher doch noch funktioniert hat? Dadurch, dass wir hier selbst einen Konstruktor definiert haben, verschwindet der Standard-Konstruktor, den wir in der Main-Methode aufrufen, automatisch.

Das heißt, sobald wir einen Konstruktor definieren, zählt dieser und der Standard-Konstruktor wird nicht mehr automatisch erzeugt.

Wie wird man die Fehlermeldung los?

Wenn wir die Fehlermeldung loswerden möchten, müssen wir also die entsprechenden Parameter angeben, die vom Konstruktor verlangt werden. Genauso, wie wir es bereits von Methoden kennen.

Wir übergeben also zunächst eine Farbe, wie beispielsweise Grün. Danach übergeben wir eine Brand, für die wir beispielhaft VW wählen. Zu guter Letzt übergeben wir noch den Wert 130 bei der PS-Anzahl.

Car car1 = new Car("Grün", "VW", 130); //Instanziierung eines Objekts

Jetzt sehen wir auch schon, dass die Fehlermeldung verschwunden ist und können das Programm ohne Probleme ausführen:

Die Fehlermeldung im Java Konstruktor ist verschwunden

Wir haben unten in der Klasse Car noch unsere Get-Methoden definiert, weshalb wir direkt überprüfen können, ob die Werte auch tatsächlich zugewiesen wurden.

Das können wir zum Beispiel mit einer Konsolenausgabe umsetzen, in der wir uns die Farbe ausgeben lassen:

Car car1 = new Car("Grün", "VW", 130); //Instanziierung eines Objekts

System.out.println(car1.getColor());

Führen wir das Programm nun aus, erscheint tatsächlich „Grün“ in der Konsole, weil wir den Wert im Konstruktor von Beginn an auf Grün gesetzt haben:

Beim Ausführen des Programms erscheint Grün in der Konsole

Was können wir im Java Konstruktor noch tun?

Jetzt, nachdem du das Wichtigste zum Java Konstruktor erfahren hast, kannst du diesen jederzeit definieren und nach eigenem Wunsch mit Werten vorbelegen.

Neben dem Vorbelegen von Attributen können wir im Konstruktor auch andere Dinge tun. Zum Beispiel könnten wir vom eigenen Objekt die Methode drive aufrufen:

this.brand = brand;
this.horsePower = horsePower;

this.drive();

Wenn wir das Programm jetzt speichern und ausführen, sehen wir „Das Auto fährt…“ in der Konsole, weil direkt im Anschluss an die Erzeugung des Objekts die Methode ausgeführt wird. Danach folgt die Konsolenausgabe der Farbe Grün:

Wir sehen durch den Java Konstruktor erst die Methode und anschließend das Attribut

Im Konstruktor kannst du alles Beliebige tun, das direkt beim Erstellen einer Instanz von einer Klasse passieren soll.

4. Zusammenfassung

Ganz wichtig zu wissen ist: Wenn du keinen Konstruktor definierst, gilt der Standard-Konstruktor.

Der Standard-Konstruktor ist ein „leerer“ Konstruktor, der das Objekt lediglich sauber im Programm aufbaut. Darin ist allerdings noch nichts Nützliches vorbereitet, das man verwenden könnte.

Wenn du allerdings Werte vorbelegt haben möchtest, musst du dir selbst einen Konstruktor definieren.

Der Konstruktoraufbau

Der Konstruktoraufbau ist dabei immer gleich: Zuerst wählt man den Sichtbarkeitsmodifizierer, der in der Regel public ist, damit man ihn auch von anderen Klassen aus, wie etwa der Klasse Program, aufrufen kann. Andere Sichtbarkeitsmodifizierer, wie beispielsweise private können an dieser Stelle aber ebenso verwendet werden.

Mit private würde allerdings der Code innerhalb der Program-Klasse nicht mehr funktionieren, weil wir von dort aus nicht auf die Klasse Car zugreifen können. Dadurch bekommen wir allgemein Schwierigkeiten, Objekte zu erstellen, weil wir von nirgendwo darauf Zugriff haben.

Es gibt gewisse Techniken, durch welche sich eine Lösung für dieses Problem finden lässt, aber das ist fortgeschrittenes Wissen, mit dem wir uns jetzt noch nicht beschäftigen werden.

Wir befinden uns noch beim normalen Konstruktor und das bedeutet, wie bereits gesagt: Wir schreiben lediglich den Sichtbarkeitsmodifizierer und den Namen der Klasse. Der Aufbau ist immer gleich.

Dann übergeben wir die gewünschten Parameter und öffnen geschweifte Klammern für einen Codeblock. In diesen schreiben wir unseren Code und damit ist der Konstruktor auch schon definiert.

Du kennst jetzt also auch den Konstruktor und weißt über den Aufbau von Objekten und Klassen Bescheid.

Darüberhinaus hast du gelernt, dass wir mit der Klasse einen Bauplan von dieser definieren, von welchem wir Objekte erzeugen können. Diese Objekte setzen sich aus Attributen und Methoden zusammen. Außerdem gibt es die Sichtbarkeitsmodifizierer, bei welchen wir beachten müssen, was wir von wo aus aufrufen können.

Zu guter Letzt hast du über den Konstruktor gelernt, dass dieser das Objekt konstruiert. Bisher erschien die Zeile rätselhaft, in welcher der new-Operator und der Klassenname aufgetaucht sind. Jetzt weißt du, dass das der Konstruktor ist.