Menu
CoddyTech

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.

challenge icon

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 Wrapper bọc văn bản bằng tiền tố và hậu tố. Lớp này cần lưu String prefix và 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 Repeater lặ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.
  • 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 Wrapper có tiền tố "[" và hậu tố "]"
    • Tạo một Wrapper khác có tiền tố "***" và hậu tố "***"
    • Tạo một Repeater lặ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ả

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
  
}
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