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: HelloA 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
EasyLet'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 fieldcustomerName(String).Inside ShoppingCart, define a nested inner class called
Itemwith two private fields:name(String) andprice(double). Give Item a constructor to initialize both fields and agetDetails()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). Insidecheckout():- Create a local inner class called
DiscountCalculatorwith a methodapplyDiscount(double originalPrice)that returns the price after applying the discount percentage. - Use the local class to calculate the final price.
- Create an anonymous inner class that implements the
Formatterinterface (you'll define this) to format the receipt. The anonymous class should override aformat()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]- Create a local inner class called
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 at10.0.Create a ShoppingCart with the customer name. Then create an Item using the outer class reference syntax:
cart.new Item(name, price). Callcheckout()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: HelloLocal 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
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsFields (Attributes)Constructor MethodConstructor OverloadingRecap - Simple Calculator4Inheritance
Basic Inheritance (extends)The super KeywordMethod Overriding (@Override)Constructor ChainingThe Object ClassSingle & Multilevel InheritWhy No Multi Class InheritRecap - Employee Hierarchy7Special Methods & Object Class
toString() Methodequals() and hashCode()clone() MethodcompareTo() and ComparableComparator InterfaceRecap - Custom Sorting2Access Modifiers & Encapsulate
Access Levels OverviewGetter and Setter MethodsInformation HidingThe final KeywordRecap - Bank Account Manager5Polymorphism
Method Overloading BasicsMethod Overriding (Run-Time)Upcasting and DowncastingThe instanceof OperatorAbstract Classes and MethodsRecap - Shape Calculator8Advanced OOP Concepts
Composition vs InheritanceAggregation vs CompositionInner Nested & Anonymous ClassEnums and Enum MethodsRecords (Java 16+)Sealed Classes (Java 17+)3Class Props & Static Member
Instance vs Static VariablesStatic MethodsStatic BlocksConstants (static final)Recap - Counter & Utility6Interfaces & Abstract Classes
Introduction to InterfacesImplementing InterfacesMulti Interface ImplemenDefault & Static in InterfaceAbstract Classes vs InterfacesFunctional InterfacesRecap - Payment System