Menu
Coddy logo textTech

Upcasting und Downcasting

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 30 von 87.

In der vorherigen Lektion hast du gesehen, wie eine Variable des übergeordneten Typs ein untergeordnetes Objekt enthalten kann: Animal myPet = new Dog(). Diese Zuweisung wird Upcasting genannt und geschieht automatisch, weil ein Dog immer ein Animal ist.

Upcasting bewegt sich in der Vererbungshierarchie nach oben. Es erfolgt implizit und ist immer sicher:

Dog dog = new Dog();
Animal animal = dog;  // Upcasting - automatisch

Beim Upcasting kannst du nur auf Methoden zugreifen, die in der übergeordneten Klasse definiert sind. Die spezifischen Methoden der Kindklasse werden verborgen, obwohl das Objekt darunter weiterhin ein Dog ist.

Downcasting geht in die entgegengesetzte Richtung und wandelt eine Elternreferenz zurück in einen untergeordneten Typ um. Dies erfordert eine explizite Typumwandlung, da es nicht immer sicher ist:

Animal animal = new Dog();  // Upcasting
Dog dog = (Dog) animal;     // Downcasting – expliziter Cast erforderlich
dog.bark();                 // Jetzt können wir auf Dog-Methoden zugreifen

Downcasting ist riskant. Wenn das Objekt nicht tatsächlich der Typ ist, in den du es umwandelst, löst Java zur Laufzeit eine ClassCastException aus:

Animal animal = new Cat();
Dog dog = (Dog) animal;  // Kompiliert, stürzt aber zur Laufzeit ab!

Der Compiler kann diesen Fehler nicht erkennen, weil er nur die deklarierten Typen sieht. Der tatsächliche Objekttyp ist erst bekannt, wenn das Programm ausgeführt wird. In der nächsten Lektion lernst du, wie du den Typ eines Objekts sicher überprüfst, bevor du ein Downcasting durchführst.

challenge icon

Aufgabe

Einfach

Erstelle ein Mediaplayer-System, das sowohl Upcasting als auch Downcasting in Aktion demonstriert. Du wirst eine Hierarchie von Medientypen erstellen und üben, zwischen Referenzen auf Eltern- und Kindklassen umzuwandeln.

Du wirst deinen Code auf vier Dateien verteilen:

  • Media.java: Erstelle die Basisklasse, die von allen Medientypen gemeinsam verwendet wird. Jedes Medienelement hat ein Feld title (String). Füge einen Konstruktor hinzu, um es zu initialisieren, eine Getter-Methode getTitle() und eine Methode play(), die Folgendes ausgibt: Playing: [title]
  • Song.java: Erstelle eine Klasse, die Media erweitert. Songs haben ein zusätzliches Feld artist (String). Verwende super für die Initialisierung der Elternklasse. Überschreibe play(), sodass Folgendes ausgegeben wird: Playing song: [title] by [artist]. Füge eine Methode showArtist() hinzu, die Folgendes ausgibt: Artist: [artist]
  • Podcast.java: Erstelle eine weitere Klasse, die Media erweitert. Podcasts haben ein Feld episode (int). Überschreibe play(), sodass Folgendes ausgegeben wird: Playing podcast: [title] - Episode [episode]. Füge eine Methode showEpisode() hinzu, die Folgendes ausgibt: Episode: [episode]
  • Main.java: Demonstriere Upcasting und Downcasting mit deinen Medientypen. Du erhältst vier Eingaben: einen Songtitel, einen Künstlernamen, einen Podcasttitel und eine Episodennummer.

    Erstelle zuerst einen Song und caste ihn zu einer Media-Referenz. Rufe play() für diese Referenz auf, um Laufzeitpolymorphie in Aktion zu sehen.

    Downcaste anschließend diese Media-Referenz zurück zu einem Song und rufe showArtist() auf, um auf die kinderspezifische Methode zuzugreifen.

    Erstelle dann einen Podcast und caste ihn zu einer Media-Referenz. Rufe play() für diese Referenz auf.

    Downcaste schließlich diese Media-Referenz zurück zu einem Podcast und rufe showEpisode() auf.

Du erhältst vier Eingaben: den Songtitel (String), den Künstlernamen (String), den Podcasttitel (String) und die Episodennummer (int).

Deine Ausgabe sollte vier Zeilen enthalten – zwei für den Song (seine Wiedergabeausgabe und die Künstlerinformationen) und zwei für den Podcast (seine Wiedergabeausgabe und die Episodeninformationen). Beachte, wie du durch Upcasting verschiedene Medientypen einheitlich behandeln kannst, während du durch Downcasting auf ihre individuellen Funktionen zugreifen kannst!

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String songTitle = scanner.nextLine();
        String artistName = scanner.nextLine();
        String podcastTitle = scanner.nextLine();
        int episodeNumber = scanner.nextInt();
        
        // TODO: Erstelle einen Song und caste ihn zu einer Media-Referenz hoch
        
        // TODO: Rufe play() auf der Media-Referenz auf (demonstriert Polymorphismus)
        
        // TODO: Caste die Media-Referenz zurück zu Song herunter
        
        // TODO: Rufe showArtist() auf der Song-Referenz auf
        
        // TODO: Erstelle einen Podcast und caste ihn zu einer Media-Referenz hoch
        
        // TODO: Rufe play() auf der Media-Referenz auf
        
        // TODO: Caste die Media-Referenz zurück zu Podcast herunter
        
        // TODO: Rufe showEpisode() auf der Podcast-Referenz auf
    }
}
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-Java-Compiler