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;Console.WriteLine(coffee.Name + ": " + coffee.Price * coffee.Quantity + " €");Kaffee: 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) { Name = name; Price = price; Quantity = quantity; }}
class Program{ static void Main() { Product coffee = new Product("Kaffee", 7.50, 2); Console.WriteLine(coffee.Name + ": " + coffee.Price * coffee.Quantity + " €"); }}Kaffee: 15 €- 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){ Name = name; Price = price; Quantity = quantity;}
Product coffee = new Product("Kaffee", 7.50, 2);Console.WriteLine(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.
- Name = name: vom Parameter in das Feld des 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
In C# heißt das Feld Name und der Parameter name. Die Namen unterscheiden sich im großen Buchstaben, deshalb ist Name = name; klar: Links steht das Feld, rechts der Parameter.
Dasselbe kannst du mit this schreiben: dem Objekt, das gerade entsteht. this.Name ist „das Feld Name dieses Objekts“:
public Product(string name, double price, int quantity){ this.Name = name; this.Price = price; this.Quantity = quantity;}Hier ist this optional. Du brauchst es, wenn Feld und Parameter gleich heißen. Solche Felder (kleingeschrieben) siehst du in der Lektion „Kapselung“: Dort ist this.balance = balance; der einzige Weg zum Feld.
Probier es aus
Finde den Fehler
Wähle die Zeile mit dem Fehler.
Name = Name; speichert das Feld in sich selbst, und es bleibt null. Du brauchst Name = name;, mit dem Parameter rechts. Der Compiler gibt nur eine Warnung (CS1717: „Assignment made to same variable“), also achte auf die Warnungen.
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 CS7036: There is no argument given that corresponds to the required parameter 'name' of 'Product.Product(string, double, int)'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){ Name = name; Price = price; 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(...) nach den Klammern ruft einen anderen Konstruktor derselben Klasse auf, bevor der Rumpf läuft. Hier ist der Rumpf leer.
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) { Name = name; Price = price; Quantity = 1; }
public Product(string name, double price, int quantity) { Name = name; Price = price; Quantity = quantity; }}
Product bread = new Product("Brot", 1.20);Product milk = new Product("Milch", 2.10, 3);Console.WriteLine(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)
{
Title = title;
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