Menu
Coddy logo textTech

Innere, verschachtelte & anonyme Klassen

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

Java ermöglicht es Ihnen, Klassen innerhalb anderer Klassen zu definieren. Diese inneren Klassen helfen dabei, Code zu organisieren, indem sie verwandte Funktionalitäten gruppieren, und können direkt auf die Member der äußeren Klasse zugreifen.

Eine geschachtelte innere Klasse ist als Mitglied einer anderen Klasse definiert. Sie hat Zugriff auf alle Felder und Methoden der äußeren Klasse, einschließlich privater:

class Outer {
    private String message = "Hello";
    
    class Inner {
        void display() {
            System.out.println(message);  // Kann auf privates Feld zugreifen
        }
    }
}

// Verwendung
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.display();  // Gibt aus: Hello

Eine lokale innere Klasse wird innerhalb einer Methode definiert. Sie kann nur innerhalb dieser Methode verwendet werden und auf lokale Variablen zugreifen, die effektiv final sind:

void process() {
    String prefix = "Result: ";
    
    class LocalHelper {
        void print(int value) {
            System.out.println(prefix + value);
        }
    }
    
    new LocalHelper().print(42);
}

Eine anonyme innere Klasse ist eine Klasse ohne Namen, die in einem einzigen Ausdruck erstellt und instanziiert wird. Sie wird häufig verwendet, um Schnittstellen zu implementieren oder Klassen spontan zu erweitern:

Comparator<String> comp = new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.length() - b.length();
    }
};

Innere Klassen sind besonders nützlich, wenn eine Klasse nur für eine andere Klasse relevant ist, wodurch Ihr Code organisiert und gekapselt bleibt.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Warenkorbsystem, das alle drei Arten innerer Klassen demonstriert. Du erstellst einen ShoppingCart, der eine verschachtelte innere Klasse zur Darstellung von Artikeln, eine lokale innere Klasse zur Berechnung von Rabatten und eine anonyme innere Klasse zur Formatierung des endgültigen Belegs verwendet.

Du organisierst deinen Code über zwei Dateien:

  • ShoppingCart.java: Erstelle die äußere Klasse, die ein Einkaufserlebnis verwaltet. Dein ShoppingCart sollte ein privates Feld customerName (String) besitzen.

    Definiere innerhalb von ShoppingCart eine verschachtelte innere Klasse namens Item mit zwei privaten Feldern: name (String) und price (double). Gib Item einen Konstruktor, der beide Felder initialisiert, sowie eine Methode getDetails(), die Folgendes zurückgibt: [name]: $[price]

    Dein ShoppingCart benötigt einen Konstruktor, der den Kundennamen entgegennimmt, sowie eine Methode namens checkout(), die ein Item und einen Rabattprozentsatz (double) akzeptiert. Innerhalb von checkout():

    1. Erstelle eine lokale innere Klasse namens DiscountCalculator mit einer Methode applyDiscount(double originalPrice), die den Preis nach Anwendung des Rabattprozentsatzes zurückgibt.
    2. Verwende die lokale Klasse, um den Endpreis zu berechnen.
    3. Erstelle eine anonyme innere Klasse, die das Formatter-Interface implementiert (dieses definierst du selbst), um den Beleg zu formatieren. Die anonyme Klasse sollte eine format()-Methode überschreiben, die einen mehrzeiligen Belegtext zurückgibt.

    Die Methode checkout() sollte den formatierten Beleg in genau diesem Format zurückgeben:

    --- Receipt ---
    Customer: [customerName]
    Item: [item details from getDetails()]
    Discount: [discount]%
    Final Price: $[calculated price]
  • Formatter.java: Definiere ein einfaches Interface mit einer einzigen Methode: String format(). Dieses Interface wird von deiner anonymen inneren Klasse innerhalb der checkout-Methode implementiert.
  • Main.java: Erwecke deinen Warenkorb zum Leben! Du erhältst drei Eingaben: Kundenname (String), Artikelname (String) und Artikelpreis (double). Der Rabattprozentsatz ist fest auf 10.0 gesetzt.

    Erstelle einen ShoppingCart mit dem Kundennamen. Erstelle anschließend ein Item mithilfe der Syntax für die Referenz auf die äußere Klasse: cart.new Item(name, price). Rufe checkout() mit dem Item und dem Rabatt auf und gib den zurückgegebenen Beleg aus.

Du erhältst drei Eingaben in dieser Reihenfolge: Kundenname, Artikelname und Artikelpreis.

Wenn die Eingaben beispielsweise Alice, Laptop und 1000.0 lauten, beträgt der Endpreis nach einem Rabatt von 10 % 900.0.

Beachte, wie jeder Typ innerer Klasse einem anderen Zweck dient: Die verschachtelte Klasse gruppiert zugehörige Daten mit der äußeren Klasse, die lokale Klasse kapselt Logik, die nur innerhalb einer Methode benötigt wird, und die anonyme Klasse bietet eine schnelle, einmalige Implementierung eines Interfaces!

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String customerName = scanner.nextLine();
        String itemName = scanner.nextLine();
        double itemPrice = scanner.nextDouble();
        
        double discount = 10.0;
        
        // TODO: Erstelle einen ShoppingCart mit dem Kundennamen
        
        // TODO: Erstelle ein Item mit: cart.new Item(itemName, itemPrice)
        
        // TODO: Rufe checkout() mit dem Item und dem Rabatt auf und gib das Ergebnis 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-Java-Compiler