Menu
Coddy logo textTech

Innere, geschachtelte & 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 kann 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

Lassen Sie uns ein Warenkorbsystem bauen, das alle drei Arten von inneren Klassen demonstriert. Sie erstellen eine ShoppingCart-Klasse, die 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.

Sie organisieren Ihren Code in zwei Dateien:

  • ShoppingCart.java: Erstellen Sie die äußere Klasse, die ein Einkaufserlebnis verwaltet. Ihr ShoppingCart sollte ein privates Feld customerName (String) haben.

    Definieren Sie innerhalb von ShoppingCart eine verschachtelte innere Klasse namens Item mit zwei privaten Feldern: name (String) und price (double). Geben Sie Item einen Konstruktor zur Initialisierung beider Felder und eine getDetails()-Methode, die Folgendes zurückgibt: [name]: $[price]

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

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

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

    --- Receipt ---
    Customer: [customerName]
    Item: [item details from getDetails()]
    Discount: [discount]%
    Final Price: $[calculated price]
  • Formatter.java: Definieren Sie ein einfaches Interface mit einer einzigen Methode: String format(). Dieses Interface wird von Ihrer anonymen inneren Klasse innerhalb der checkout-Methode implementiert.
  • Main.java: Erwecken Sie Ihren Warenkorb zum Leben! Sie erhalten drei Eingaben: Kundenname (String), Artikelname (String) und Artikelpreis (double). Der Rabattprozentsatz ist auf 10.0 festgelegt.

    Erstellen Sie einen ShoppingCart mit dem Kundennamen. Erstellen Sie dann ein Item unter Verwendung der Syntax für äußere Klassenreferenzen: cart.new Item(name, price). Rufen Sie checkout() mit dem Artikel und dem Rabatt auf und geben Sie den zurückgegebenen Beleg aus.

Sie erhalten drei Eingaben in der folgenden Reihenfolge: Kundenname, Artikelname und Artikelpreis.

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

Beachten Sie, wie jeder Typ der inneren Klasse einem anderen Zweck dient: Die verschachtelte Klasse gruppiert verwandte 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!

Spickzettel

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

Verschachtelte innere Klasse

Eine verschachtelte innere Klasse wird als Element einer anderen Klasse definiert. Sie hat Zugriff auf alle Felder und Methoden der äußeren Klasse, einschließlich privater Elemente:

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

Lokale innere Klasse

Eine lokale innere Klasse wird innerhalb einer Methode definiert. Sie kann nur innerhalb dieser Methode verwendet werden und kann 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);
}

Anonyme innere Klasse

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.

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