Zum Inhalt
wannacode

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 + " €");
Ausgabe
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.

Program.cs
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 + " €");
}
}
Ausgabe
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
  1. new legt ein neues Objekt an. Seine Felder haben Standardwerte.
  2. Der Konstruktor läuft. Die Argumente werden in seine Parameter kopiert.
  3. Name = name: vom Parameter in das Feld des Objekts.
  4. Dasselbe für Preis und Stückzahl.
  5. Der Konstruktor ist fertig, und die Parameter verschwinden. coffee bekommt einen Pfeil auf das fertige Objekt.
  6. 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

Das Programm soll „Tee: 3.2 €“ ausgeben. Der Preis erscheint, der Name nicht. In welcher Zeile ist der Fehler?

Wähle die Zeile mit dem Fehler.

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();
Fehler beim Kompilieren
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);
Antwort

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;
    }
}

Ü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.

Ausgabe
Maria, 34 Jahre
Peter, 19 Jahre

2. Tier. Eine Klasse Animal mit Art und Alter. Erzeuge eine 3 Jahre alte Katze und einen 7 Jahre alten Hund.

Ausgabe
Art: Katze, Alter: 3
Art: Hund, Alter: 7

3. Tanzschritt. Eine Klasse DanceMove mit Name und Dauer in Sekunden. In der Lektion „Instanzmethoden“ lernt der Schritt, sich selbst „auszuführen“.

Ausgabe
moonwalk: 5 Sek.

Weitere Aufgaben

  • Ein Buch mit Konstruktor. Schreib Book aus der letzten Lektion mit einem Konstruktor Book(title, author) neu. Wie viele Zeilen sparst du in Main?
  • Ein Produkt mit zwei Konstruktoren. Product mit 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 Booking mit 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

1. Wann läuft der Konstruktor?
2. Welcher Rückgabetyp steht vor dem Namen des Konstruktors?
3. Die Klasse hat nur einen Konstruktor Product(name, price). Was passiert bei new Product()?
4. Was ist this in einem Konstruktor?
5. Die Klasse hat zwei Konstruktoren: einen mit Name und Preis und einen mit Name, Preis und Stückzahl. Wie heißt das?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·