Java cho phép chúng ta định nghĩa một lớp trong một lớp khác, những lớp như thế được gọi là lớp lồng nhau (nested class).
class OuterClass { ... class NestedClass { ... } }
Lớp lồng nhau mà không phải là static
thì còn được gọi là lớp nội (inner class).
Lớp lồng không static
(tức lớp nội) có thể truy xuất đến tất cả các thuộc tính và phương thức của lớp lồng bên ngoài, kể cả các thành phần private,
nhưng lớp lồng static
thì lại không thể.
Lớp lồng có các công dụng như:
- Gom nhóm các lớp có chung mục đích lại với nhau
- Tăng tính đóng gói
- Tăng tính dễ đọc và dễ bảo trì cho code
Lớp lồng static – Static Nested Class
Giống như phương thức và thuộc tính, lớp lồng static
được gắn kết với đối tượng thuộc lớp bao bọc lấy nó nhưng không thể truy xuất tới các thuộc tính và phương thức của đối tượng đó.
Chúng ta truy xuất tới lớp lồng static
bằng cách thêm dấu chấm và tên lớp:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Lớp nội – Inner Class
Lớp nội được gắn với đối tượng thuộc lớp bao bọc lấy nó và có thể truy xuất tới các phương thức và thuộc tính thuộc đối tượng đó, nhưng không thể định nghĩa các thuộc tính và đối tượng static
.
Đối tượng của lớp nội chỉ tồn tại trong đối tượng của lớp bao bọc lấy nó.
class OuterClass { ... class InnerClass { ... } }
Để tạo một đối tượng lớp nội thì chúng ta phải tạo lớp ngoài trước. Sau đó tạo đối tượng lớp nội theo cú pháp như sau:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Lớp nội còn có 2 loại nữa là lớp cục bộ và lớp ẩn, chúng ta sẽ tìm hiểu sau.
Biến trùng tên
Khi chúng ta khai báo các thuộc tính nằm trong các khu vực con mà có tên giống nhau, thì các biến nằm trong cùng sẽ được dùng trước tiên. Ví dụ:
public class LevelOne { public int x = 0; class LevelTwo { public int x = 1; void methodLevelTwo(int x) { System.out.println("x = " + x); System.out.println("this.x = " + this.x); System.out.println("LevelOne.this.x = " + LevelOne.this.x); } } public static void main(String[] args) { LevelOne lo = new LevelOne(); LevelOne.LevelTwo lt = lo.new LevelTwo(); lt.methodLevelTwo(23); } }
Trong đoạn code trên, chúng ta có 3 biến tên là x
, một biến là thuộc tính của lớp LevelOne,
một biến là thuộc tính của lớp LevelTwo
, một biến là tham số của phương thức methodLevelTwo()
. Khi chúng ta sử dụng đến biến x
trong phương thức methodLevelTwo()
thì Java sẽ tự động hiểu là dùng biến trong tham số, muốn truy xuất đến biến x
của lớp LevelTwo
thì chúng ta phải dùng từ khóa this
, muốn truy xuất đến biến x
của lớp LevelOne
thì chúng ta phải ghi rõ tên lớp rồi tới từ khóa this
.
Đoạn code trên sẽ in ra các kết quả sau:
x = 23 this.x = 1 LevelOne.this.x = 0