Lớp có thể gọi
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 84 trên 110.
Trong Dart, bạn có thể khiến các đối tượng của một lớp có thể được gọi như hàm bằng cách triển khai phương thức call(). Nhờ đó, bạn có thể dùng cú pháp gọi hàm với một đối tượng, tức là đặt dấu ngoặc đơn trực tiếp sau đối tượng.
class Multiplier {
final int factor;
Multiplier(this.factor);
int call(int value) {
return value * factor;
}
}
void main() {
var double = Multiplier(2);
var triple = Multiplier(3);
print(double(5)); // 10: gọi đối tượng như một hàm (function)
print(triple(5)); // 15
}Khi bạn viết double(5), Dart tự động gọi phương thức call() với 5 làm đối số. Đối tượng hoạt động như một hàm mà vẫn giữ trạng thái của nó (trường factor).
Phương thức call() có thể có bất kỳ chữ ký nào: nhiều tham số, tham số tùy chọn hoặc thậm chí trả về các kiểu dữ liệu khác nhau:
class Greeter {
final String greeting;
Greeter(this.greeting);
String call(String name, {String punctuation = '!'}) {
return '$greeting, $name$punctuation';
}
}
void main() {
var hello = Greeter('Hello');
print(hello('Alice')); // Hello, Alice!
print(hello('Bob', punctuation: '.')); // Hello, Bob.
}Các lớp có thể gọi (callable class) hữu ích khi bạn cần hành vi giống hàm (function) kết hợp với trạng thái hoặc cấu hình. Chúng thường được dùng để tạo các thao tác, bộ kiểm tra hoặc phép biến đổi có thể tái sử dụng và cần ghi nhớ các thiết lập giữa những lần gọi.
Thử thách
DễHãy xây dựng hệ thống định dạng văn bản bằng các lớp có thể gọi! Bạn sẽ tạo các đối tượng có thể gọi như hàm để biến đổi văn bản theo nhiều cách, đồng thời giữ nguyên cấu hình riêng của chúng.
Bạn sẽ sắp xếp code thành hai tệp:
formatters.dart: Tạo hai lớp có thể gọi để biến đổi văn bản:- Một lớp
Wrapperbọc văn bản bằng tiền tố và hậu tố. Lớp này cần lưuString prefixvàString suffix. Khi được gọi với tham sốString text, lớp sẽ trả về văn bản được bọc giữa tiền tố và hậu tố. - Một lớp
Repeaterlặp lại văn bản một số lần nhất định. Lớp này cần lưu giá trịint times. Khi được gọi với tham sốString text, lớp sẽ trả về văn bản được lặp lại số lần đó, với một dấu cách giữa mỗi lần lặp.
- Một lớp
main.dart: Nhập các bộ định dạng và minh họa cách hoạt động của các lớp có thể gọi:- Tạo một
Wrappercó tiền tố"["và hậu tố"]" - Tạo một
Wrapperkhác có tiền tố"***"và hậu tố"***" - Tạo một
Repeaterlặp lại 3 lần - Gọi bộ bọc đầu tiên với
"Hello"và in ra kết quả - Gọi bộ bọc thứ hai với
"Important"và in ra kết quả - Gọi bộ lặp với
"Go"và in ra kết quả - Cuối cùng, kết hợp chúng: gọi bộ bọc đầu tiên với kết quả của việc gọi bộ lặp với
"Dart", rồi in ra kết quả
- Tạo một
Hãy chú ý cách mỗi đối tượng định dạng ghi nhớ cấu hình của mình và có thể được gọi trực tiếp bằng dấu ngoặc đơn, giống như một hàm!
Đầu ra dự kiến:
[Hello]
***Important***
Go Go Go
[Dart Dart Dart]Tự làm thử
import 'formatters.dart';
void main() {
// TODO: Tạo một Wrapper với tiền tố "[" và hậu tố "]"
// TODO: Tạo một Wrapper khác với tiền tố "***" và hậu tố "***"
// TODO: Tạo một Repeater lặp lại 3 lần
// TODO: Gọi Wrapper đầu tiên với "Hello" và in kết quả ra
// TODO: Gọi Wrapper thứ hai với "Important" và in kết quả ra
// TODO: Gọi Repeater với "Go" và in kết quả ra
// TODO: Kết hợp chúng: gọi Wrapper đầu tiên với kết quả của việc
// gọi Repeater với "Dart", rồi in kết quả ra
}
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