Menu
Coddy logo textTech

Sealed Classes (Java 17+)

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

Im traditionellen Java kann jede andere Klasse eine Klasse erweitern, wenn Sie sie erstellen (es sei denn, Sie markieren sie als final). Aber was ist, wenn Sie Vererbung zulassen möchten, aber nicht von jedem? Java 17 hat versiegelte Klassen (sealed classes) eingeführt, um Ihnen eine präzise Kontrolle darüber zu geben, welche Klassen Ihre erweitern können.

Eine versiegelte Klasse (sealed class) deklariert ihre zulässigen Unterklassen explizit unter Verwendung der Schlüsselwörter sealed und permits:

sealed abstract class Shape permits Circle, Rectangle, Triangle {
    abstract double area();
}

final class Circle extends Shape {
    double radius;
    double area() { return Math.PI * radius * radius; }
}

final class Rectangle extends Shape {
    double width, height;
    double area() { return width * height; }
}

final class Triangle extends Shape {
    double base, height;
    double area() { return 0.5 * base * height; }
}

Nur Circle, Rectangle und Triangle können Shape erweitern. Jede andere Klasse, die versucht, sie zu erweitern, führt zu einem Kompilierungsfehler.

Jede zulässige Unterklasse muss einen von drei Modifikatoren verwenden: final (keine weitere Erweiterung), sealed (setzt die Einschränkungskette fort) oder non-sealed (öffnet sich für uneingeschränkte Erweiterung):

sealed class Vehicle permits Car, Truck { }

final class Car extends Vehicle { }           // Kann nicht erweitert werden
non-sealed class Truck extends Vehicle { }    // Jeder kann Truck erweitern

Sealed Classes sind besonders leistungsfähig in Verbindung mit Pattern Matching in Switch-Ausdrücken, da der Compiler alle möglichen Subtypen kennt und die Vollständigkeit überprüfen kann. Sie sind ideal für die Modellierung einer festen Menge von Typen innerhalb einer Domäne, wie zum Beispiel Zahlungsmethoden, Antworttypen oder geometrische Formen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Benachrichtigungssystem bauen, das versiegelte Klassen (sealed classes) demonstriert, indem es einschränkt, welche Arten von Benachrichtigungen in Ihrer Anwendung existieren können. Sie werden eine Hierarchie erstellen, in der nur bestimmte Benachrichtigungstypen zulässig sind und jeder Typ die Zustellung unterschiedlich handhabt.

Sie werden Ihren Code über vier Dateien organisieren:

  • Notification.java: Erstellen Sie eine versiegelte abstrakte Klasse (sealed abstract class), die als Basis für alle Benachrichtigungen dient. Sie sollte genau drei Unterklassen zulassen: EmailNotification, SMSNotification und PushNotification. Ihre versiegelte Klasse benötigt ein geschütztes Feld message (String), einen Konstruktor zu dessen Initialisierung, einen Getter für die Nachricht und eine abstrakte Methode deliver(), die einen String zurückgibt, der beschreibt, wie die Benachrichtigung gesendet wird.
  • EmailNotification.java: Erstellen Sie eine final Klasse, die Notification erweitert. Eine EmailNotification hat ein zusätzliches privates Feld recipient (String) für die E-Mail-Adresse. Ihr Konstruktor sollte sowohl die Nachricht als auch den Empfänger entgegennehmen und den Eltern-Konstruktor mit super() aufrufen. Die Methode deliver() sollte zurückgeben: "Sending email to " + recipient + ": " + message
  • SMSNotification.java: Erstellen Sie eine non-sealed Klasse, die Notification erweitert – dies ermöglicht es anderen Klassen, sie in Zukunft bei Bedarf zu erweitern. Eine SMSNotification hat ein zusätzliches privates Feld phoneNumber (String). Ihr Konstruktor nimmt die Nachricht und die Telefonnummer entgegen. Die Methode deliver() sollte zurückgeben: "Sending SMS to " + phoneNumber + ": " + message
  • PushNotification.java: Erstellen Sie eine final Klasse, die Notification erweitert. Eine PushNotification hat ein zusätzliches privates Feld deviceId (String). Ihr Konstruktor nimmt die Nachricht und die Geräte-ID entgegen. Die Methode deliver() sollte zurückgeben: "Sending push to device " + deviceId + ": " + message
  • Main.java: Führen Sie Ihr Benachrichtigungssystem zusammen! Sie erhalten vier Eingaben: eine Nachricht (String), eine E-Mail-Adresse (String), eine Telefonnummer (String) und eine Geräte-ID (String).

    Erstellen Sie jeweils eine Instanz jedes Benachrichtigungstyps unter Verwendung derselben Nachricht, aber mit den jeweiligen Kontaktinformationen. Speichern Sie alle drei in einem Array vom Typ Notification[], um Polymorphie mit versiegelten Klassen zu demonstrieren. Iterieren Sie dann durch das Array und geben Sie das Ergebnis des Aufrufs von deliver() für jede Benachrichtigung aus.

Sie erhalten vier Eingaben in der Reihenfolge: Nachricht, E-Mail-Adresse, Telefonnummer und Geräte-ID.

Beachten Sie, wie die versiegelte Klasse die Hierarchie einschränkt – nur die drei zulässigen Klassen können Notification erweitern. Jede Unterklasse muss sich selbst als final, sealed oder non-sealed deklarieren. Dies gibt Ihnen die vollständige Kontrolle über Ihre Typhierarchie, während Polymorphie weiterhin ermöglicht wird!

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lies die vier Eingaben ein
        String message = scanner.nextLine();
        String email = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        String deviceId = scanner.nextLine();
        
        // TODO: Erstelle von jedem Benachrichtigungstyp eine Instanz mit derselben Nachricht
        // - EmailNotification mit message und email
        // - SMSNotification mit message und phoneNumber
        // - PushNotification mit message und deviceId
        
        // TODO: Speichere alle drei Benachrichtigungen in einem Notification[] Array
        // Dies demonstriert Polymorphismus mit sealed classes
        
        // TODO: Iteriere durch das Array und gib das Ergebnis von deliver() aus
        // für jede Benachrichtigung
        
    }
}
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