Menu
Coddy logo textTech

Upcasting & Downcasting

Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 29 von 70.

Beim Arbeiten mit Vererbungshierarchien musst du häufig zwischen Basis- und abgeleiteten Typen konvertieren. Upcasting konvertiert einen abgeleiteten Typ in seinen Basistyp, während Downcasting das Gegenteil bewirkt.

Upcasting erfolgt implizit und ist immer sicher, da eine abgeleitete Klasse garantiert alles besitzt, was die Basisklasse besitzt:

Dog myDog = new Dog();
Animal animal = myDog;  // Upcasting - implizit, funktioniert immer

Ein Downcasting erfordert eine explizite Typumwandlung und kann zur Laufzeit fehlschlagen, wenn das Objekt nicht tatsächlich der Typ ist, in den du es umwandelst:

Animal animal = new Dog();
Dog dog = (Dog)animal;  // Downcasting - funktioniert, weil es wirklich ein Dog ist

Animal cat = new Cat();
Dog wrong = (Dog)cat;   // Wirft InvalidCastException!

Um sicher nach unten zu casten, verwende zuerst das Schlüsselwort is, um den Typ zu überprüfen, oder verwende as, das statt eine Ausnahme auszulösen null zurückgibt:

if (animal is Dog d)
{
    d.Bark();  // Sicher - d ist nur verfügbar, wenn die Prüfung erfolgreich ist
}

Dog maybeDog = animal as Dog;
if (maybeDog != null)
{
    maybeDog.Bark();
}

Der Musterabgleich mit is wird im modernen C# bevorzugt, weil er die Typprüfung und die Typumwandlung in einem Schritt kombiniert und deinen Code dadurch sowohl sicherer als auch übersichtlicher macht.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Fahrzeuginspektionssystem, das zeigt, wie Upcasting und Downcasting dir ermöglichen, flexibel mit Objekten in einer Vererbungshierarchie zu arbeiten. Du erstellst verschiedene Fahrzeugtypen und schreibst Code, der bestimmte Fahrzeugarten sicher erkennt und mit ihnen interagiert.

Du organisierst deinen Code auf vier Dateien verteilt:

  • Vehicle.cs: Definiere eine Basisklasse Vehicle im Namespace Inspection. Jedes Fahrzeug verfügt über eine LicensePlate-Eigenschaft (string), die über einen Konstruktor festgelegt wird. Füge eine Methode namens GetBasicInfo() hinzu, die "Vehicle: {LicensePlate}" zurückgibt.
  • Car.cs: Definiere eine Klasse Car im Namespace Inspection, die von Vehicle erbt. Autos verfügen über eine zusätzliche NumberOfDoors-Eigenschaft (int). Der Konstruktor akzeptiert sowohl das Kennzeichen als auch die Anzahl der Türen. Füge eine Methode namens Honk() hinzu, die "{LicensePlate} honks: Beep beep!" zurückgibt.
  • Motorcycle.cs: Definiere eine Klasse Motorcycle im Namespace Inspection, die von Vehicle erbt. Motorräder verfügen über eine HasSidecar-Eigenschaft (bool). Der Konstruktor akzeptiert das Kennzeichen und den Beiwagenstatus. Füge eine Methode namens Rev() hinzu, die "{LicensePlate} revs: Vroom!" zurückgibt.
  • Program.cs: In deiner Hauptdatei erstellst du Fahrzeuge und übst sowohl Upcasting als auch sicheres Downcasting. Erstelle mithilfe von Eingabewerten ein Car und ein Motorcycle und speichere beide in einem Array von Vehicle-Referenzen (Upcasting). Durchlaufe das Array und gib für jedes Fahrzeug seine grundlegenden Informationen aus. Verwende anschließend das Schlüsselwort is mit Pattern Matching, um sicher downzucasten: Wenn es sich um ein Car handelt, rufe Honk() auf; wenn es sich um ein Motorcycle handelt, rufe Rev() auf.

Du erhältst vier Eingaben:

  • Kennzeichen des Autos
  • Anzahl der Türen
  • Kennzeichen des Motorrads
  • Beiwagen vorhanden (true oder false)

Gib die Ausgabe für jedes Fahrzeug im Array in diesem Format aus:

{GetBasicInfo() result}
{Honk() or Rev() result based on actual type}

Wenn die Eingaben beispielsweise ABC-123, 4, XYZ-789 und false lauten, sollte die Ausgabe wie folgt aussehen:

Vehicle: ABC-123
ABC-123 honks: Beep beep!
Vehicle: XYZ-789
XYZ-789 revs: Vroom!

Beachte, dass alle Fahrzeuge als Vehicle-Referenzen gespeichert werden (Upcasting), du aber ihre tatsächlichen Typen sicher ermitteln und mithilfe der is-Pattern-Matching-Syntax für das Downcasting typspezifische Methoden aufrufen kannst!

Probier es selbst

using System;
using Inspection;

class Program
{
    public static void Main(string[] args)
    {
        // Eingaben lesen
        string carPlate = Console.ReadLine();
        int numberOfDoors = Convert.ToInt32(Console.ReadLine());
        string motorcyclePlate = Console.ReadLine();
        bool hasSidecar = Convert.ToBoolean(Console.ReadLine());
        
        // TODO: Erstelle ein Car-Objekt unter Verwendung von carPlate und numberOfDoors
        
        // TODO: Erstelle ein Motorcycle-Objekt unter Verwendung von motorcyclePlate und hasSidecar
        
        // TODO: Erstelle ein Array von Vehicle-Referenzen, das beide Fahrzeuge enthält (Upcasting)
        
        // TODO: Durchlaufe das Array in einer Schleife und für jedes Fahrzeug:
        //   - Gib das Ergebnis von GetBasicInfo() aus
        //   - Verwende das Schlüsselwort 'is' mit Pattern Matching für ein sicheres Downcasting:
        //     - Wenn es ein Car ist, rufe Honk() auf und gib es aus
        //     - Wenn es ein Motorcycle ist, rufe Rev() auf und gib es aus
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C#-Compiler