Menu
Coddy logo textTech

Inner Nested & Anonymous Class

Part of the Object Oriented Programming section of Coddy's Java journey — lesson 49 of 87.

Java allows you to define classes inside other classes. These inner classes help organize code by grouping related functionality together and can access the outer class's members directly.

A nested inner class is defined as a member of another class. It has access to all fields and methods of the outer class, including private ones:

class Outer {
    private String message = "Hello";
    
    class Inner {
        void display() {
            System.out.println(message);  // Can access private field
        }
    }
}

// Usage
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.display();  // Prints: Hello

A local inner class is defined inside a method. It can only be used within that method and can access local variables that are effectively final:

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

An anonymous inner class is a class without a name, created and instantiated in one expression. It's commonly used for implementing interfaces or extending classes on the fly:

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

Inner classes are particularly useful when a class is only relevant to one other class, keeping your code organized and encapsulated.

challenge icon

Challenge

Easy

Let's build a shopping cart system that showcases all three types of inner classes. You'll create a ShoppingCart that uses a nested inner class to represent items, a local inner class to calculate discounts, and an anonymous inner class to format the final receipt.

You'll organize your code across two files:

  • ShoppingCart.java: Create the outer class that manages a shopping experience. Your ShoppingCart should have a private field customerName (String).

    Inside ShoppingCart, define a nested inner class called Item with two private fields: name (String) and price (double). Give Item a constructor to initialize both fields and a getDetails() method that returns: [name]: $[price]

    Your ShoppingCart needs a constructor that takes the customer name, and a method called checkout() that accepts an Item and a discount percentage (double). Inside checkout():

    1. Create a local inner class called DiscountCalculator with a method applyDiscount(double originalPrice) that returns the price after applying the discount percentage.
    2. Use the local class to calculate the final price.
    3. Create an anonymous inner class that implements the Formatter interface (you'll define this) to format the receipt. The anonymous class should override a format() method that returns a multi-line receipt string.

    The checkout() method should return the formatted receipt string with this exact format:

    --- Receipt ---
    Customer: [customerName]
    Item: [item details from getDetails()]
    Discount: [discount]%
    Final Price: $[calculated price]
  • Formatter.java: Define a simple interface with a single method: String format(). This interface will be implemented by your anonymous inner class inside the checkout method.
  • Main.java: Bring your shopping cart to life! You'll receive three inputs: customer name (String), item name (String), and item price (double). The discount percentage is fixed at 10.0.

    Create a ShoppingCart with the customer name. Then create an Item using the outer class reference syntax: cart.new Item(name, price). Call checkout() with the item and discount, and print the returned receipt.

You will receive three inputs in order: customer name, item name, and item price.

For example, if the inputs are Alice, Laptop, and 1000.0, the final price after a 10% discount would be 900.0.

Notice how each inner class type serves a different purpose: the nested class groups related data with the outer class, the local class encapsulates logic needed only within one method, and the anonymous class provides a quick, one-time implementation of an interface!

Cheat sheet

Java allows you to define classes inside other classes. These inner classes help organize code by grouping related functionality together and can access the outer class's members directly.

Nested Inner Class

A nested inner class is defined as a member of another class. It has access to all fields and methods of the outer class, including private ones:

class Outer {
    private String message = "Hello";
    
    class Inner {
        void display() {
            System.out.println(message);  // Can access private field
        }
    }
}

// Usage
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.display();  // Prints: Hello

Local Inner Class

A local inner class is defined inside a method. It can only be used within that method and can access local variables that are effectively final:

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

Anonymous Inner Class

An anonymous inner class is a class without a name, created and instantiated in one expression. It's commonly used for implementing interfaces or extending classes on the fly:

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

Inner classes are particularly useful when a class is only relevant to one other class, keeping your code organized and encapsulated.

Try it yourself

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Read inputs
        String customerName = scanner.nextLine();
        String itemName = scanner.nextLine();
        double itemPrice = scanner.nextDouble();
        
        double discount = 10.0;
        
        // TODO: Create a ShoppingCart with the customer name
        
        // TODO: Create an Item using: cart.new Item(itemName, itemPrice)
        
        // TODO: Call checkout() with the item and discount, then print the result
        
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming