Konstruktoren und this
Kurz gesagt: Ein Konstruktor ist eine besondere Methode mit dem Namen der Klasse, die bei new läuft und die Felder des neuen Objekts füllt, und this ist das Objekt selbst.
Problem
Kaffee für 0 €
Du erzeugst ein Produkt, genau wie in der letzten Lektion, und füllst die Felder Zeile für Zeile. Eine Zeile hast du vergessen:
Product coffee = new Product();coffee.name = "Kaffee";coffee.quantity = 2;System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €");Kaffee: 0.0 €Der Kaffee kostet 0 €. Der Compiler beschwert sich nicht: Aus seiner Sicht hat der Preis einen Wert, 0. Je mehr Felder eine Klasse hat, desto leichter vergisst du eines. Und ein Produkt ohne Preis sollte es gar nicht geben können.
Die Idee
Konstruktor: ohne diese Daten kein Objekt
Eine Klasse kann sagen, was sie braucht, bevor du ein Objekt aus ihr erzeugen kannst. Dafür gibt es den Konstruktor: eine besondere Methode, die bei new läuft.
class Product { public String name; public double price; public int quantity;
public Product(String name, double price, int quantity) { this.name = name; this.price = price; this.quantity = quantity; }}
public class Main { public static void main(String[] args) { Product coffee = new Product("Kaffee", 7.50, 2); System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €"); }}Kaffee: 15.0 €- Der Konstruktor hat genau denselben Namen wie die Klasse:
Product. - Er hat keinen Rückgabetyp, nicht einmal
void. - Seine Parameter sind die Daten, ohne die ein Produkt nicht auskommt. Du übergibst sie in den Klammern von
new:new Product("Kaffee", 7.50, 2).
Jetzt kannst du den Preis nicht mehr vergessen. Wenn du zwei Argumente statt drei übergibst, lässt sich das Programm nicht kompilieren.
public Product(String name, double price, int quantity) { this.name = name; this.price = price; this.quantity = quantity;}
Product coffee = new Product("Kaffee", 7.50, 2);System.out.println(coffee.name + ": " + coffee.price * coffee.quantity + " €");Schritt für Schritt, in Worten
- new legt ein neues Objekt an. Seine Felder haben Standardwerte.
- Der Konstruktor läuft. Die Argumente werden in seine Parameter kopiert.
- this.name = name: vom Parameter in das Feld dieses Objekts.
- Dasselbe für Preis und Stückzahl.
- Der Konstruktor ist fertig, und die Parameter verschwinden. coffee bekommt einen Pfeil auf das fertige Objekt.
- Das Objekt kommt schon gefüllt aus new, deshalb ist der Preis nicht 0.
Die Idee
this: das Feld dieses Objekts
Im Konstruktor gibt es zwei Dinge namens name: den Parameter und das Feld. Der bloße Name ist der Parameter, weil er „näher“ ist. Für das Feld schreibst du this.name.
public Product(String name, double price, int quantity) { this.name = name; this.price = price; this.quantity = quantity;}this ist das Objekt, das gerade entsteht. this.name = name; bedeutet „speichere den Parameter name im Feld name dieses Objekts“.
Die Parameter könnten auch anders heißen (productName), dann bräuchtest du kein this. Gleiche Namen sind in Java aber üblich, weil du sofort siehst, welcher Parameter in welches Feld gehört.
Probier es aus
Finde den Fehler
Wähle die Zeile mit dem Fehler.
name = name; speichert den Parameter in sich selbst. Das Feld bleibt null. Du brauchst this.name = name;. Der Compiler meldet keinen Fehler, deshalb ist so ein Fehler schwer zu finden.
Die Idee
Und new Product() aus der letzten Lektion?
In der letzten Lektion gab es keinen Konstruktor, und new Product() hat funktioniert. Wenn du keinen Konstruktor schreibst, fügt der Compiler einen leeren ohne Parameter hinzu. Er heißt Standardkonstruktor und lässt die Felder bei ihren Standardwerten.
Sobald du einen eigenen Konstruktor schreibst, ist der leere weg:
Product empty = new Product();error: constructor Product in class Product cannot be applied to given types;Genau darum geht es: Ein Produkt ohne Name und Preis lässt sich nicht mehr erzeugen. Wenn du trotzdem einen leeren Konstruktor brauchst, schreib ihn selbst.
Die Idee
Mehrere Konstruktoren
Die meisten Produkte im Warenkorb kommen einzeln. Jedes Mal 1 zu tippen wird lästig.
Du kannst der Klasse einen zweiten Konstruktor geben, ohne die Stückzahl. Er steht neben dem ersten:
public Product(String name, double price) { this.name = name; this.price = price; this.quantity = 1;}Das ist das Überladen aus dem Modul „Methoden“: ein Name, verschiedene Parameter. Bei new wählt der Compiler den Konstruktor anhand der Argumente.
Genauer, für Neugierige
Die beiden Konstruktoren wiederholen dieselben Zeilen. Stattdessen kann der kürzere den längeren aufrufen:
public Product(String name, double price) { this(name, price, 1);}this(...) ruft einen anderen Konstruktor derselben Klasse auf. Es muss die erste Zeile im Konstruktor sein.
Wenn du morgen eine Prüfung des Preises hinzufügst, schreibst du sie so nur in einen Konstruktor.
Probier es aus
Welcher Konstruktor?
Was gibt das Programm aus?
class Product { public String name; public double price; public int quantity;
public Product(String name, double price) { this.name = name; this.price = price; this.quantity = 1; }
public Product(String name, double price, int quantity) { this.name = name; this.price = price; this.quantity = quantity; }}
Product bread = new Product("Brot", 1.20);Product milk = new Product("Milch", 2.10, 3);System.out.println(bread.quantity + " " + milk.quantity);new Product("Brot", 1.20) hat zwei Argumente, also wird der Konstruktor mit zwei Parametern aufgerufen. Er speichert die Stückzahl 1. Für die Milch werden drei Argumente übergeben, also wird der andere Konstruktor aufgerufen.Probier es aus
Wie heißt der Konstruktor?
Was steht in der Lücke?
class Book {
public String title;
public String author;
public (String title, String author) {
this.title = title;
this.author = author;
}
}Book: Der Konstruktor hat genau denselben Namen wie die Klasse, mit demselben großen Anfangsbuchstaben.Übung
Objekte, die vollständig entstehen
Löse die Aufgaben in deinem Editor. Jede Klasse bekommt einen Konstruktor mit Parametern für alle ihre Felder.
1. Person. Eine Klasse Person mit Name und Alter. Erzeuge zwei Personen und gib ihre Daten aus.
Maria, 34 JahrePeter, 19 Jahre2. Tier. Eine Klasse Animal mit Art und Alter. Erzeuge eine 3 Jahre alte Katze und einen 7 Jahre alten Hund.
Art: Katze, Alter: 3Art: Hund, Alter: 73. Tanzschritt. Eine Klasse DanceMove mit Name und Dauer in Sekunden. In der Lektion „Instanzmethoden“ lernt der Schritt, sich selbst „auszuführen“.
moonwalk: 5 Sek.Weitere Aufgaben
- Ein Buch mit Konstruktor. Schreib
Bookaus der letzten Lektion mit einem KonstruktorBook(title, author)neu. Wie viele Zeilen sparst du in main? -
Ein Produkt mit zwei Konstruktoren.
Productmit zwei Konstruktoren, wie in der Lektion. Leg ein Array{ new Product("Brot", 1.20, 2), new Product("Kaffee", 7.50) }an und gib von jedem Name und Stückzahl aus: „Brot x2“, „Kaffee x1“. Lass dann den kürzeren Konstruktor den längeren aufrufen. - Buchung. Eine Klasse
Bookingmit dem Namen des Gastes, der Anzahl der Nächte und dem Preis pro Nacht. Gib aus, was der Aufenthalt kostet: Für 3 Nächte zu 85 € sind das 255 €.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Methoden · Parameter und return · Überladen · Klassen und Objekte
- Geht weiter in: Instanzmethoden · Kapselung · static: was alle Objekte teilen · Vererbung
- Aufgaben zum Thema: Klassen und Objekte