Menu
CoddyTech

Phương thức call()

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 73 trên 110.

Dart có một phương thức đặc biệt tên là call(), cho phép bạn dùng một đối tượng như thể đó là một hàm. Khi một lớp định nghĩa phương thức call(), bạn có thể gọi các đối tượng của lớp đó bằng cú pháp gọi hàm.

class Multiplier {
  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 (object) như một hàm (function)
  print(triple(5));  // 15
}

Thay vì viết double.call(5), bạn chỉ cần viết double(5). Dart tự động gọi phương thức call() khi bạn dùng dấu ngoặc đơn với đối tượng.

Phương thức call() có thể nhận bất kỳ tham số nào và trả về bất kỳ kiểu dữ liệu nào, giống như một phương thức thông thường:

class Greeter {
  String prefix;
  
  Greeter(this.prefix);
  
  String call(String name, {String punctuation = '!'}) {
    return '$prefix, $name$punctuation';
  }
}

void main() {
  var hello = Greeter('Hello');
  print(hello('Alice'));  // Hello, Alice!
  print(hello('Bob', punctuation: '?'));  // Hello, Bob?
}

Mẫu này hữu ích khi bạn cần các đối tượng hoạt động như hàm nhưng cũng duy trì trạng thái hoặc cấu hình. Mẫu này thường được dùng để tạo các thao tác, bộ kiểm tra hoặc bộ định dạng 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.

challenge icon

Thử thách

Dễ

Hãy tạo một hệ thống định dạng văn bản, trong đó bạn có thể gọi trực tiếp các đối tượng định dạng như hàm! Bạn sẽ tạo các lớp có thể gọi để biến đổi văn bản theo nhiều cách khác nhau, đồng thời giữ nguyên các thiết lập cấu hình của chúng.

Bạn sẽ sắp xếp code vào hai tệp:

  • formatters.dart: Tạo hai lớp có thể gọi để biến đổi chuỗi:
    • Lớp Wrapper thêm tiền tố và hậu tố có thể tùy chỉnh vào văn bản. Lớp này cần lưu trữ các chuỗi prefix và suffix, còn phương thức call() cần nhận String text và trả về văn bản được bao quanh bởi tiền tố và hậu tố.
    • Lớp Repeater lặp lại văn bản một số lần có thể tùy chỉnh. Lớp này cần lưu trữ một số nguyên times, còn phương thức call() cần nhận String text và trả về văn bản được lặp lại số lần tương ứng, cách nhau bằng dấu cách.
  • main.dart: Nhập các lớp định dạng và minh họa cách dùng những đối tượng này như hàm:
    • Tạo một Wrapper với tiền tố '[' và hậu tố ']'
    • Tạo một Wrapper khác với tiền tố '***' và hậu tố '***'
    • Tạo một Repeater với times được đặt thành 3
    • Gọi wrapper thứ nhất với 'Hello' và in ra kết quả
    • Gọi wrapper thứ hai với 'Important' và in ra kết quả
    • Gọi repeater với 'Go' và in ra kết quả
    • Minh họa cách nối chuỗi thao tác bằng cách truyền kết quả của wrapper thứ nhất (với 'Nested') vào wrapper thứ hai, rồi in ra kết quả

Hãy chú ý cách bạn có thể gọi trực tiếp các đối tượng định dạng bằng dấu ngoặc đơn, giống như các hàm thông thường. Phương thức call() giúp bạn làm được điều này, và mỗi đối tượng sẽ ghi nhớ cấu hình của nó qua các lần sử dụng!

Đầu ra dự kiến:

[Hello]
***Important***
Go Go Go
***[Nested]***

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 với times đặt thành 3
  
  // TODO: Gọi Wrapper đầu tiên với 'Hello' và in kết quả
  
  // TODO: Gọi Wrapper thứ hai với 'Important' và in kết quả
  
  // TODO: Gọi Repeater với 'Go' và in kết quả
  
  // TODO: Minh họa cách nối chuỗi bằng cách truyền kết quả của Wrapper đầu tiên
  // (với 'Nested') vào Wrapper thứ hai, rồi in kết quả
}
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch Dart online