Trong bài viết này, bạn sẽ tìm hiểu về lớp Sealed, cách chúng được tạo ra và khi nào sử dụng chúng với sự trợ giúp của các ví dụ.
Các lớp niêm phong được sử dụng khi một giá trị có thể chỉ có một trong các kiểu từ một tập hợp giới hạn (cấu trúc phân cấp bị hạn chế).
Trước khi đi vào chi tiết về các lớp niêm phong, hãy cùng khám phá xem chúng giải quyết vấn đề gì. Hãy lấy một ví dụ (lấy từ trang web chính thức của Kotlin - bài báo về các lớp kín):
class Expr class Const(val value: Int) : Expr class Sum(val left: Expr, val right: Expr) : Expr fun eval(e: Expr): Int = when (e) ( is Const -> e.value is Sum -> eval(e.right) + eval(e.left) else -> throw IllegalArgumentException("Unknown expression") )
Trong chương trình trên, lớp cơ sở Expr có hai lớp dẫn xuất Const (biểu diễn một số) và Sum (biểu diễn tổng của hai biểu thức). Ở đây, bắt buộc phải sử dụng else
nhánh cho điều kiện mặc định trong biểu thức when.
Bây giờ, nếu bạn lấy một lớp con mới từ Expr
lớp, trình biên dịch sẽ không phát hiện ra bất kỳ thứ gì khi else
nhánh xử lý nó, điều này có thể dẫn đến lỗi. Sẽ tốt hơn nếu trình biên dịch báo lỗi khi chúng tôi thêm một lớp con mới.
Để giải quyết vấn đề này, bạn có thể sử dụng lớp niêm phong. Như đã đề cập, lớp niêm phong hạn chế khả năng tạo các lớp con. Và, khi bạn xử lý tất cả các lớp con của một lớp niêm phong trong một when
biểu thức, thì không cần thiết phải sử dụng else
nhánh.
Để tạo một lớp niêm phong, công cụ sửa đổi niêm phong được sử dụng. Ví dụ,
Lớp kín Expr
Ví dụ: Lớp kín
Đây là cách bạn có thể giải quyết vấn đề trên bằng cách sử dụng lớp niêm phong:
sealed class Expr class Const(val value: Int) : Expr() class Sum(val left: Expr, val right: Expr) : Expr() object NotANumber : Expr() fun eval(e: Expr): Int = when (e) ( is Const -> e.value is Sum -> eval(e.right) + eval(e.left) NotANumber -> java.lang.Double.NaN )
Như bạn thấy, không có else
chi nhánh. Nếu bạn lấy một lớp con mới từ Expr
lớp, trình biên dịch sẽ khiếu nại trừ khi lớp con được xử lý trong when
biểu thức.
Vài lưu ý quan trọng
- Tất cả các lớp con của một lớp niêm phong phải được khai báo trong cùng một tệp nơi khai báo lớp niêm phong.
- Bản thân một lớp được niêm phong là trừu tượng và bạn không thể khởi tạo các đối tượng từ nó.
- Bạn không thể tạo các hàm tạo không riêng tư của một lớp được niêm phong; các hàm tạo của chúng là
private
theo mặc định.
Sự khác biệt giữa Enum và Sealed Class
Lớp Enum và lớp niêm phong khá giống nhau. Tập hợp các giá trị cho một kiểu enum cũng bị hạn chế giống như một lớp được niêm phong.
Sự khác biệt duy nhất là, enum có thể chỉ có một cá thể duy nhất, trong khi một lớp con của một lớp niêm phong có thể có nhiều cá thể.