Menu
Coddy logo textTech

Methodenüberschreibung (Laufzeit)

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

Während die Methodenüberladung zur Kompilierzeit aufgelöst wird, veranschaulicht die Methodenüberschreibung den Laufzeitpolymorphismus. Hier entscheidet Java, welche Methode ausgeführt werden soll, wenn das Programm tatsächlich läuft, und zwar anhand des tatsächlichen Typs des Objekts und nicht anhand des deklarierten Typs der Variable.

Sie haben im Kapitel über Vererbung etwas über das Überschreiben von Methoden gelernt. Was es polymorph macht, ist die Art und Weise, wie Java damit umgeht, wenn eine Referenz der Elternklasse auf ein Objekt der Kindklasse verweist:

public class Animal {
    public void speak() {
        System.out.println("Some sound");
    }
}

public class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Bark!");
    }
}

public class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Meow!");
    }
}

Beobachten Sie nun, was passiert, wenn wir Referenzen vom Typ der Elternklasse verwenden:

Animal myPet = new Dog();
myPet.speak();  // Ausgabe: Bark!

myPet = new Cat();
myPet.speak();  // Ausgabe: Meow!

Obwohl myPet als Animal deklariert ist, ruft Java die überschriebene Methode basierend auf dem tatsächlichen Objekttyp zur Laufzeit auf. Dies wird als dynamischer Methodenaufruf bezeichnet. Die JVM schaut sich an, was das Objekt wirklich ist, nicht was die Variable besagt.

Dies ermöglicht leistungsstarke Muster, wie die einheitliche Verarbeitung verschiedener Objekte:

Animal[] pets = {new Dog(), new Cat(), new Dog()};
for (Animal pet : pets) {
    pet.speak();  // Jedes ruft seine eigene Version auf
}

Laufzeit-Polymorphismus ermöglicht es Ihnen, flexiblen Code zu schreiben, der mit Elterntypen arbeitet, während er automatisch das korrekte Verhalten der Kindtypen verwendet.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Benachrichtigungssystem, das Laufzeitpolymorphie in Aktion demonstriert. Du erstellst eine Hierarchie von Benachrichtigungstypen, bei der derselbe Methodenaufruf abhängig vom tatsächlichen Objekttyp zur Laufzeit unterschiedliche Ausgaben erzeugt.

Du organisierst deinen Code auf vier Dateien:

  • Notification.java: Erstelle die Basisklasse, die alle Benachrichtigungen gemeinsam haben. Jede Benachrichtigung besitzt ein Feld recipient (String). Füge einen Konstruktor zu seiner Initialisierung, eine Getter-Methode und eine Methode send() hinzu, die Folgendes ausgibt: Sending notification to [recipient]
  • EmailNotification.java: Erstelle eine Klasse, die Notification erweitert. E-Mail-Benachrichtigungen fügen ein Feld subject hinzu. Verwende super für die Initialisierung des übergeordneten Elements. Überschreibe die Methode send(), sodass sie Folgendes ausgibt: Emailing [recipient]: [subject]
  • SMSNotification.java: Erstelle eine weitere Klasse, die Notification erweitert. SMS-Benachrichtigungen fügen ein Feld phoneNumber hinzu. Überschreibe send(), sodass Folgendes ausgegeben wird: Texting [phoneNumber] for [recipient]
  • Main.java: Hier zeigt sich die Laufzeitpolymorphie in ihrer ganzen Stärke! Du erhältst drei Eingaben: einen Empfängernamen, einen E-Mail-Betreff und eine Telefonnummer. Erstelle ein Array von Notification-Referenzen, das drei Objekte in dieser Reihenfolge enthält: eine Basis-Notification, eine EmailNotification und eine SMSNotification (alle mit demselben Empfänger). Durchlaufe anschließend das Array und rufe für jedes Element send() auf. Beobachte, wie Java automatisch die richtige überschriebene Version aufruft, abhängig davon, was jedes Objekt tatsächlich ist!

Du erhältst drei Eingaben: den Namen des Empfängers (String), den E-Mail-Betreff (String) und die Telefonnummer (String).

Deine Ausgabe sollte drei Zeilen enthalten – jeder Aufruf von send() erzeugt eine andere Ausgabe, obwohl du dieselbe Methode für Notification-Referenzen aufrufst. Das ist dynamisches Methoden-Dispatching in Aktion!

REQUIRED OUTPUT FORMAT: [Your translated content here]

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String recipient = scanner.nextLine();
        String subject = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        
        // TODO: Erstelle ein Array von Notification-Referenzen mit 3 Elementen
        // Das Array sollte (in dieser Reihenfolge) Folgendes enthalten:
        // 1. Ein Basis-Notification-Objekt
        // 2. Ein EmailNotification-Objekt
        // 3. Ein SMSNotification-Objekt
        // Alle verwenden denselben recipient
        
        // TODO: Iteriere durch das Array und rufe send() für jedes Element auf
        // Dies demonstriert Laufzeit-Polymorphismus!
    }
}
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