Khái niệm về Inner Class
Trong Java, Inner Class (Lớp nội) là một thành phần quan trọng trong cấu trúc lớp, bên cạnh biến thành viên, phương thức và constructor. Khi một lớp được khai báo bên trong phạm vi của một lớp khác, nó được gọi là Inner Class. Kỹ thuật này thường được áp dụng khi một đối tượng là một phần logic gắn liền với lớp bao bọc và không cần thiết phải tách ra thành một file riêng biệt.
Phân loại Inner Class
Inner Class được chia thành bốn loại chính: Lớp nội thành viên (Member Inner Class), Lớp nội tĩnh (Static Inner Class), Lớp nội cục bộ (Local Inner Class) và Lớp nội danh ẩn (Anonymous Inner Class).
1. Member Inner Class (Lớp nội thành viên)
Đây là loại lớp nội phổ biến nhất, đóng vai trò như một thành viên thông thường của lớp bao bọc (tương tự như biến hoặc phương thức).
public class HeThong {
private String phienBan = "v1.0";
public static String tenHeThong = "QuanLyNhanSu";
public class BoPhan {
private String tenBoPhan;
private int maSo = 101;
public void hienThi() {
// Truy cập trực tiếp biến của lớp nội
System.out.println(maSo); // 101
// Truy cập biến static của lớp bao bọc
System.out.println(tenHeThong); // QuanLyNhanSu
int maSo = 505;
System.out.println(maSo); // 505 (biến cục bộ)
System.out.println(this.maSo); // 101 (biến của lớp nội)
System.out.println(HeThong.this.phienBan); // v1.0 (biến của lớp bao bọc)
}
}
}
Để khởi tạo đối tượng của lớp nội thành viên, bạn cần thông qua một đối tượng của lớp bao bọc:
// Cu pháp: LopBaoBoc.LopNoi bien = new LopBaoBoc().new LopNoi();
HeThong.BoPhan bp = new HeThong().new BoPhan();
bp.hienThi();
2. Static Inner Class (Lớp nội tĩnh)
Lớp nội tĩnh được khai báo với từ khóa static. Nó thuộc về chính lớp bao bọc thay vì thuộc về một thực thể (instance) cụ thể.
public class Kho {
private int soLuong = 50;
public static String maKho = "WH001";
public static class QuanLy {
public void kiemTra() {
// Có thể truy cập biến static của lớp bao bọc
System.out.println(maKho);
// Không thể truy cập trực tiếp biến instance của lớp bao bọc
// System.out.println(soLuong); // Lỗi biên dịch
}
}
}
Khởi tạo lớp nội tĩnh không cần đối tượng của lớp bao bọc:
// Cú pháp: LopBaoBoc.LopNoi bien = new LopBaoBoc.LopNoi();
Kho.QuanLy ql = new Kho.QuanLy();
ql.kiemTra();
3. Local Inner Class (Lớp nội cục bộ)
Lớp này được định nghĩa bên trong một khối mã (thông thường là một phương thức). Phạm vi hoạt động của nó chỉ nằm trong phương thức đó, tương tự như một biến cục bộ.
public class XuLyDuLieu {
public void thucThi() {
class CongCu {
public void chay() {
System.out.println("Cong cu dang hoat dong...");
}
}
// Chỉ có thể khởi tạo và sử dụng ngay trong phương thức
CongCu cc = new CongCu();
cc.chay();
}
}
4. Anonymous Inner Class (Lớp nội danh ẩn)
Đây là một dạng đặc biệt của lớp nội cục bộ nhưng không có tên lớp cụ thể. Nó thường được dùng để ghi đè (override) phương thức của một lớp hoặc interface ngay tại thời điểm khởi tạo.
Giả sử chúng ta có một lớp trừu tượng:
public abstract class ThongBao {
public abstract void gui();
}
Sử dụng lớp nội danh ẩn để tạo đối tượng mà không cần tạo file class con:
public class UngDung {
public static void main(String[] args) {
// Khởi tạo một lớp con ẩn danh của ThongBao
ThongBao tb = new ThongBao() {
@Override
public void gui() {
System.out.println("Dang gui thong bao qua Email...");
}
};
tb.gui();
}
}
Ứng dụng của Anonymous Inner Class: Kỹ thuật này giúp rút gọn mã nguồn khi cần truyền một đối tượng triển khai interface hoặc abstract class vào một phương thức mà không muốn định nghĩa một lớp riêng biệt.
public interface HanhDong {
void thucHien();
}
public class Controller {
public static void main(String[] args) {
// Truyền trực tiếp implementation thông qua lớp ẩn danh
kichHoat(new HanhDong() {
@Override
public void thucHien() {
System.out.println("He thong bat dau chay!");
}
});
}
public static void kichHoat(HanhDong h) {
System.out.println("Chuan bi...");
h.thucHien();
System.out.println("Hoan tat.");
}
}