Lớp sealed (Dart 3)
Thuộc phần Lập trình hướng đối tượng trong hành trình Dart của Coddy. Bài học 85 trên 110.
Dart 3 giới thiệu lớp sealed (sealed classes), giúp giới hạn những lớp nào có thể kế thừa hoặc triển khai chúng. Khi đánh dấu một lớp là sealed, chỉ những lớp trong cùng tệp mới có thể là kiểu con trực tiếp của lớp đó. Điều này tạo ra một tập hợp khép kín gồm các kiểu con đã biết.
sealed class Result {}
class Success extends Result {
final String data;
Success(this.data);
}
class Failure extends Result {
final String error;
Failure(this.error);
}Sức mạnh của lớp sealed (sealed class) đến từ việc kiểm tra tính đầy đủ. Khi dùng switch với một kiểu sealed, trình biên dịch biết tất cả kiểu con có thể có và đảm bảo bạn xử lý từng kiểu:
String handleResult(Result result) {
return switch (result) {
Success(data: var d) => 'Got: $d',
Failure(error: var e) => 'Error: $e',
};
// Không cần default vì trình biên dịch biết mọi trường hợp đều đã được xử lý!
}
void main() {
var success = Success('Hello');
var failure = Failure('Not found');
print(handleResult(success)); // Got: Hello
print(handleResult(failure)); // Error: Not found
}Nếu bạn thêm một kiểu con mới vào lớp sealed, trình biên dịch sẽ báo lỗi ở mọi câu lệnh switch không xử lý kiểu con đó. Vì vậy, lớp sealed rất phù hợp để mô hình hóa trạng thái, kết quả hoặc bất kỳ tình huống nào có một tập hợp biến thể cố định. Khác với lớp trừu tượng, lớp sealed đảm bảo rằng không có code bên ngoài nào có thể thêm kiểu con ngoài dự kiến.
Thử thách
DễHãy xây dựng trình xử lý yêu cầu mạng bằng các lớp sealed! Bạn sẽ tạo một hệ thống an toàn về kiểu, mô hình hóa các trạng thái khác nhau của phản hồi mạng, đảm bảo mọi kết quả có thể xảy ra đều được xử lý đúng cách.
Bạn sẽ sắp xếp code vào hai tệp:
response.dart: Tạo hệ thống phân cấp lớp sealed đại diện cho mọi trạng thái có thể có của phản hồi mạng:- Một lớp sealed tên là
NetworkResponse, làm lớp cơ sở cho mọi kiểu phản hồi - Một lớp
Loadingmở rộngNetworkResponse, có trườngString message(ví dụ: "Fetching data...") - Một lớp
Successmở rộngNetworkResponse, có trườngString datavà trườngint statusCode - Một lớp
Errormở rộngNetworkResponse, có trườngString errorMessagevà trườngint errorCode
- Một lớp sealed tên là
main.dart: Nhập tệp phản hồi của bạn và tạo một hàm xử lý mọi kiểu phản hồi bằng biểu thức switch:- Tạo hàm
handleResponse(NetworkResponse response)trả vềString - Dùng biểu thức switch kết hợp với so khớp mẫu để xử lý từng trường hợp:
- Với
Loading: trả vềStatus: [message] - Với
Success: trả vềSuccess ([statusCode]): [data] - Với
Error: trả vềError ([errorCode]): [errorMessage]
- Với
- Tạo ba đối tượng phản hồi và in ra kết quả xử lý từng đối tượng:
- Một
Loadingcó thông báoPlease wait... - Một
Successcó dữ liệuUser profile loadedvà mã trạng thái200 - Một
Errorcó thông báo lỗiNot foundvà mã lỗi404
- Một
- Tạo hàm
Điểm hay của các lớp sealed là trình biên dịch đảm bảo bạn xử lý mọi kiểu phản hồi có thể xảy ra, không cần trường hợp mặc định!
Đầu ra dự kiến:
Status: Please wait...
Success (200): User profile loaded
Error (404): Not foundTự làm thử
import 'response.dart';
// TODO: Tạo hàm (function) handleResponse(NetworkResponse response)
// trả về một String
// Dùng biểu thức switch kết hợp khớp mẫu để xử lý từng trường hợp:
// - Với Loading: trả về "Status: [message]"
// - Với Success: trả về "Success ([statusCode]): [data]"
// - Với Error: trả về "Error ([errorCode]): [errorMessage]"
void main() {
// TODO: Tạo một instance Loading với message "Please wait..."
// TODO: Tạo một instance Success với data "User profile loaded" và mã trạng thái 200
// TODO: Tạo một instance Error với error message "Not found" và mã lỗi 404
// TODO: In ra kết quả xử lý từng response
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng về lập trình hướng đối tượng
Tệp bên ngoàiThư viện và câu lệnh importGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcBiến thể hiệnKiến thức cơ bản về hàm khởi tạoÔn tập: Máy tính đơn giản4An toàn với giá trị null
Giới thiệu về an toàn với giá trị nullCó thể null và không thể nullToán tử ? và !Từ khóa late và an toàn với giá trị nullToán tử xử lý nullAn toàn với giá trị null trong lớpÔn tập: hệ thống hồ sơ người dùng7Lớp trừu tượng và interface
Lớp trừu tượngPhương thức trừu tượngInterface trong DartInterface ngầm địnhTriển khai và kế thừaNhiều interfaceÔn tập: Máy tính hình10Bộ sưu tập và kiểu tổng quát
Tổng quan về List, Set và MapBộ sưu tập an toàn về kiểuLớp tổng quátPhương thức tổng quátRàng buộc kiểu tổng quátIterable và IteratorÔn tập: Lưu trữ tổng quát13Khái niệm OOP nâng cao
Composition và kế thừaPhương thức mở rộngLớp có thể gọiLớp sealed (Dart 3)Records (Dart 3)Mẫu và đối sánh (3.0)Enum có phương thức2Hàm khởi tạo trong Dart
Hàm khởi tạo mặc địnhHàm khởi tạo có tênDanh sách khởi tạoHàm khởi tạo hằng sốHàm khởi tạo nhà máyHàm khởi tạo chuyển hướngÔn tập: Trình tạo hình dạng5Đóng gói
Thành viên công khai và riêng tưQuy ước tiền tố _Tính riêng tư ở cấp thư việnTìm hiểu sâu về getter và setterChe giấu thông tinÔn tập: hồ sơ học sinh8Mixin
Giới thiệu về MixinTạo MixinSử dụng nhiều MixinTừ khóa on trong MixinMixin và kế thừaMixin và giao diệnÔn tập: hệ thống động vật3Thuộc tính của lớp
Thành viên instance và thành viên tĩnhTrường final và constBiến latePhương thức và trường tĩnhGetter và setterÔn tập: trình quản lý tài khoản ngân hàng6Kế thừa
Kế thừa cơ bảnTừ khóa superGhi đè phương thứcChú thích @overrideTừ khóa lớp finalHàm khởi tạo và kế thừaÔn tập: phân cấp nhân viên9Đa hình
Khái niệm cơ bản về đa hìnhĐa hình qua giao diệnKiểm tra kiểu lúc chạyToán tử is và asTừ khóa hiệp biếnÔn tập: Bộ xử lý thanh toánTự luyện tập: Trình biên dịch Dart online