Menu
Coddy logo textTech

Generische Klassen

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

Nachdem Sie nun verstehen, warum Generics nützlich sind, lassen Sie uns Ihre eigene generische Klasse erstellen. Eine generische Klasse deklariert einen oder mehrere Typparameter in spitzen Klammern nach dem Klassennamen, die dann in der gesamten Klasse verwendet werden können.

class Box<T> {
    private T content;
    
    public void set(T content) {
        this.content = content;
    }
    
    public T get() {
        return content;
    }
}

Das T ist ein Typparameter – ein Platzhalter, der durch einen tatsächlichen Typ ersetzt wird, wenn Sie eine Instanz erstellen. Sie können jeden beliebigen Namen verwenden, aber einzelne Großbuchstaben sind üblich: T für Type, E für Element, K für Key, V für Value.

Beim Instanziieren einer generischen Klasse geben Sie den tatsächlichen Typ in spitzen Klammern an:

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get();  // Kein Casting erforderlich

Box<Integer> intBox = new Box<>();
intBox.set(42);
Integer num = intBox.get();

Beachten Sie den <> (Diamond-Operator) auf der rechten Seite – Java leitet den Typ aus der Deklaration ab. Sie können auch mehrere Typparameter für Klassen verwenden, die mit mehr als einem Typ arbeiten müssen:

class Pair<K, V> {
    private K key;
    private V value;
    
    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }
    
    public K getKey() { return key; }
    public V getValue() { return value; }
}

Pair<String, Integer> pair = new Pair<>("age", 25);
challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Geschenkregistersystem bauen, das die Leistungsfähigkeit generischer Klassen demonstriert. Sie erstellen ein flexibles Aufbewahrungssystem, das jede Art von Geschenkartikel aufnehmen kann, sowie ein Register, das Geschenk Namen mit ihren Details unter Verwendung mehrerer Typparameter verknüpft.

Sie werden Ihren Code über drei Dateien organisieren:

  • GiftBox.java: Erstellen Sie eine generische Klasse, die jede Art von Geschenk verpacken kann. Ihre GiftBox<T> sollte ein privates Feld item vom Typ T und ein privates Feld wrapped (boolean) haben, das als false beginnt. Fügen Sie einen Konstruktor hinzu, der das Element akzeptiert, eine getItem()-Methode, die das Element zurückgibt, eine wrap()-Methode, die wrapped auf true setzt, und eine isWrapped()-Methode, die den Verpackungsstatus zurückgibt. Fügen Sie eine getStatus()-Methode hinzu, die entweder [item] (wrapped) oder [item] (unwrapped) zurückgibt, abhängig vom Verpackungszustand.
  • Registry.java: Erstellen Sie eine generische Klasse mit zwei Typparametern, die einen Empfänger mit seinem Geschenk verknüpft. Ihre Registry<K, V> sollte private Felder recipient vom Typ K und gift vom Typ V haben. Fügen Sie einen Konstruktor hinzu, der beide Werte akzeptiert, Getter-Methoden getRecipient() und getGift() sowie eine getEntry()-Methode, die Folgendes zurückgibt: [recipient] -> [gift]
  • Main.java: Erwecken Sie Ihr Geschenkregister zum Leben! Sie erhalten drei Eingaben: einen Empfängernamen (String), eine Geschenkbezeichnung (String) und einen Geschenkwert (Ganzzahl, die Dollar darstellt).

    Erstellen Sie zuerst eine GiftBox<String>, die die Geschenkbezeichnung enthält. Verpacken Sie diese mit der wrap()-Methode und geben Sie dann ihren Status aus.

    Erstellen Sie als Nächstes eine GiftBox<Integer>, die den Geschenkwert enthält (der einen Geschenkkartenbetrag darstellt). Verpacken Sie diese nicht – geben Sie ihren Status aus, um zu zeigen, dass sie unverpackt ist.

    Erstellen Sie schließlich eine Registry<String, String>, die den Empfängernamen mit der Geschenkbezeichnung verknüpft, und geben Sie den Registereintrag aus.

Sie erhalten drei Eingaben in der folgenden Reihenfolge: Empfängername, Geschenkbezeichnung und Geschenkwert (als Ganzzahl).

Beachten Sie, wie dieselbe GiftBox-Klasse nahtlos mit den Typen String und Integer funktioniert – das ist die Schönheit von Generics! Und die Registry-Klasse zeigt, wie mehrere Typparameter es Ihnen ermöglichen, flexible Paarungen zwischen zwei beliebigen Typen zu erstellen.

Spickzettel

Eine generische Klasse deklariert einen oder mehrere Typparameter in spitzen Klammern nach dem Klassennamen, die innerhalb der gesamten Klasse verwendet werden können:

class Box<T> {
    private T content;
    
    public void set(T content) {
        this.content = content;
    }
    
    public T get() {
        return content;
    }
}

Das T ist ein Typparameter – ein Platzhalter, der beim Erstellen einer Instanz durch einen tatsächlichen Typ ersetzt wird. Gängige Konventionen verwenden einzelne Großbuchstaben: T für Type, E für Element, K für Key, V für Value.

Geben Sie bei der Instanziierung einer generischen Klasse den tatsächlichen Typ in spitzen Klammern an:

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get();  // No casting needed

Box<Integer> intBox = new Box<>();
intBox.set(42);
Integer num = intBox.get();

Der <> (Diamond-Operator) ermöglicht es Java, den Typ aus der Deklaration abzuleiten.

Verwenden Sie mehrere Typparameter für Klassen, die mit mehr als einem Typ arbeiten:

class Pair<K, V> {
    private K key;
    private V value;
    
    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }
    
    public K getKey() { return key; }
    public V getValue() { return value; }
}

Pair<String, Integer> pair = new Pair<>("age", 25);

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String recipientName = scanner.nextLine();
        String giftDescription = scanner.nextLine();
        int giftValue = scanner.nextInt();
        
        // TODO: Erstelle eine GiftBox<String>, die die Geschenkbeschreibung enthält
        // TODO: Verpacke sie mit der wrap()-Methode
        // TODO: Gib ihren Status mit getStatus() aus
        
        // TODO: Erstelle eine GiftBox<Integer>, die den Geschenkwert enthält
        // TODO: Diese nicht verpacken - gib ihren Status aus (sollte als unverpackt angezeigt werden)
        
        // TODO: Erstelle ein Registry<String, String>, das den Empfänger mit der Geschenkbeschreibung verknüpft
        // TODO: Gib den Registereintrag mit getEntry() 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