# Bài 13: Local Inner Class trong Java

#### I. Định nghĩa và ví dụ cụ thể

**Định nghĩa Local Inner Class:**

Local Inner Class là một lớp được khai báo bên trong một phương thức, một khối mã hoặc một vòng lặp. Local Inner Class chỉ có thể được truy cập bên trong phương thức, khối mã hoặc vòng lặp nơi nó được khai báo. Local Inner Class có thể truy cập các biến local của phương thức bao ngoài chỉ khi các biến đó được khai báo là `final` (trong các phiên bản Java trước Java 8) hoặc `effectively final` (từ Java 8 trở đi).

**Ví dụ cụ thể:**

```java
public class OuterClass {
    private String outerField = "Outer Field";

    public void display() {
        // Biến local
        final String localVariable = "Local Variable";

        // Local Inner Class
        class LocalInnerClass {
            public void print() {
                System.out.println("Accessing: " + outerField);
                System.out.println("Accessing: " + localVariable);
            }
        }

        LocalInnerClass localInner = new LocalInnerClass();
        localInner.print();
    }

    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        outer.display();
    }
}
```

**Giải thích:**

Trong ví dụ trên, `LocalInnerClass` là một Local Inner Class được khai báo bên trong phương thức `display` của lớp `OuterClass`. Phương thức `print` trong `LocalInnerClass` có thể truy cập trực tiếp biến instance `outerField` của lớp bao ngoài và biến local `localVariable` của phương thức `display`.

#### II. Ứng dụng trong thực tế

**Các trường hợp sử dụng Local Inner Class:**

1. **Xử lý các nhiệm vụ ngắn hạn:**
    

Local Inner Class thường được sử dụng để xử lý các nhiệm vụ ngắn hạn mà không cần phải khai báo một lớp riêng biệt. Điều này giúp mã nguồn trở nên gọn gàng và dễ đọc hơn.

```java
public class Button {
    public void onClick() {
        // Local Inner Class để xử lý sự kiện nhấp chuột
        class ClickHandler {
            public void handle() {
                System.out.println("Button clicked!");
            }
        }

        ClickHandler handler = new ClickHandler();
        handler.handle();
    }

    public static void main(String[] args) {
        Button button = new Button();
        button.onClick();
    }
}
```

**Giải thích:**

Trong ví dụ này, `ClickHandler` là một Local Inner Class được khai báo bên trong phương thức `onClick` của lớp `Button`. Điều này giúp nhóm mã xử lý sự kiện nhấp chuột vào một nơi và làm cho mã nguồn dễ đọc hơn.

2. **Tăng cường bảo mật:**
    

Local Inner Class có thể giúp tăng cường bảo mật bằng cách giới hạn khả năng truy cập của lớp lồng nhau vào bên trong phương thức hoặc khối mã nơi nó được khai báo. Điều này đặc biệt hữu ích khi bạn muốn ẩn các chi tiết triển khai cụ thể chỉ sử dụng một lần.

```java
public class BankAccount {
    private double balance;

    public BankAccount(double balance) {
        this.balance = balance;
    }

    public void processTransaction(double amount) {
        // Local Inner Class
        class Transaction {
            public void deposit() {
                balance += amount;
                System.out.println("Deposited: $" + amount);
            }

            public void withdraw() {
                if (amount <= balance) {
                    balance -= amount;
                    System.out.println("Withdrew: $" + amount);
                } else {
                    System.out.println("Insufficient balance");
                }
            }
        }

        Transaction transaction = new Transaction();
        if (amount > 0) {
            transaction.deposit();
        } else {
            transaction.withdraw();
        }

        System.out.println("Current balance: $" + balance);
    }

    public static void main(String[] args) {
        BankAccount account = new BankAccount(1000.00);
        account.processTransaction(200.00);  // Gọi để nạp tiền
        account.processTransaction(-150.00); // Gọi để rút tiền
    }
}
```

**Giải thích:**

Trong ví dụ này, `Transaction` là một Local Inner Class được khai báo bên trong phương thức `processTransaction` của lớp `BankAccount`. Điều này giúp bảo vệ các chi tiết xử lý giao dịch chỉ trong phạm vi của phương thức `processTransaction`.

#### III. Bài tập thực hành

**Bài tập:** Tạo một hệ thống quản lý lịch làm việc sử dụng Local Inner Class.

**Yêu cầu:**

1. Tạo lớp `Schedule` với phương thức `addTask(String task, String time)`.
    
2. Tạo một Local Inner Class `Task` bên trong phương thức `addTask` với các thuộc tính `task` và `time`.
    
3. Tạo các phương thức trong `Task` để hiển thị thông tin công việc.
    
4. Viết chương trình chính để tạo các đối tượng `Schedule` và thêm các công việc vào lịch làm việc, sau đó hiển thị thông tin của chúng.
    

**Mã nguồn mẫu:**

```java
import java.util.ArrayList;
import java.util.List;

public class Schedule {
    private List<String> tasks = new ArrayList<>();

    public void addTask(String task, String time) {
        // Local Inner Class
        class Task {
            private String task;
            private String time;

            public Task(String task, String time) {
                this.task = task;
                this.time = time;
            }

            public void display() {
                System.out.println("Task: " + task + " at " + time);
            }
        }

        Task newTask = new Task(task, time);
        tasks.add(task + " at " + time);
        newTask.display();
    }

    public void displaySchedule() {
        System.out.println("Schedule:");
        for (String task : tasks) {
            System.out.println(task);
        }
    }

    public static void main(String[] args) {
        Schedule schedule = new Schedule();
        schedule.addTask("Meeting", "10:00 AM");
        schedule.addTask("Lunch", "12:00 PM");
        schedule.addTask("Conference Call", "3:00 PM");

        schedule.displaySchedule();
    }
}
```

**Giải thích:**

Trong bài tập này, chúng ta tạo một hệ thống quản lý lịch làm việc sử dụng Local Inner Class. Lớp `Task` là một Local Inner Class được khai báo bên trong phương thức `addTask` của lớp `Schedule`. Điều này giúp nhóm mã xử lý thông tin công việc vào một nơi và làm cho mã nguồn dễ đọc hơn.

#### Tổng kết

Bài học này cung cấp một cái nhìn chi tiết về Local Inner Class trong Java, bao gồm định nghĩa, ứng dụng thực tế và các ví dụ minh họa cụ thể. Việc nắm vững khái niệm này sẽ giúp bạn tổ chức mã nguồn một cách khoa học và bảo mật hơn, đồng thời tăng khả năng tái sử dụng mã nguồn trong các dự án phần mềm.
