Menu
CoddyTech

Tạo Mixin

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

Bây giờ bạn đã hiểu mixin là gì, hãy cùng tìm hiểu cách tạo chúng cho đúng. Mixin được khai báo bằng từ khóa mixin thay vì class.

mixin Logging {
  void log(String message) {
    print('[LOG] $message');
  }
  
  void logError(String error) {
    print('[ERROR] $error');
  }
}

Mixin có thể chứa phương thức, thuộc tính, thậm chí cả getter và setter, giống như lớp. Tuy nhiên, có một quy tắc quan trọng: mixin không thể có hàm khởi tạo. Vì mixin được thiết kế để được trộn vào thay vì khởi tạo trực tiếp, chúng không cần logic khởi tạo.

mixin Timestamped {
  DateTime createdAt = DateTime.now();
  
  String get formattedTime => createdAt.toString();
  
  void printTimestamp() {
    print('Created at: $formattedTime');
  }
}

class Document with Timestamped {
  String title;
  Document(this.title);
}

void main() {
  var doc = Document('Report');
  doc.printTimestamp();  // Sử dụng phương thức (method) của mixin
  print(doc.createdAt);  // Sử dụng thuộc tính (property) của mixin
}

Khi áp dụng một mixin bằng with, tất cả thành viên của nó trở thành một phần của lớp bạn. Lớp đó có thể sử dụng trực tiếp các thành viên này, và mọi đoạn code có một instance của lớp đó cũng vậy. Nhờ đó, mixin là cách gọn gàng để bổ sung chức năng có thể tái sử dụng mà không cần đến hệ thống kế thừa phức tạp.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống nhắn tin để minh họa cách tạo mixin có phương thức, thuộc tính và getter. Bạn sẽ thiết kế một mixin bổ sung khả năng định dạng cho nhiều loại tin nhắn.

Bạn sẽ sắp xếp code thành hai tệp:

  • messaging.dart: Định nghĩa mixin và các lớp tin nhắn tại đây:
    • Một mixin Formattable gồm:
      • Thuộc tính String prefix được khởi tạo bằng '>>>'
      • Getter separator trả về ' | '
      • Phương thức format(String text) trả về chuỗi [prefix][separator][text]
      • Phương thức formatBold(String text) trả về **[text]**
    • Một lớp TextMessage sử dụng mixin Formattable. Thêm thuộc tính String sender cùng hàm khởi tạo. Thêm phương thức send(String content) để in ra kết quả gọi format() với [sender]: [content]
    • Một lớp AlertMessage cũng sử dụng mixin Formattable. Thêm thuộc tính String level cùng hàm khởi tạo. Thêm phương thức alert(String content) để in ra kết quả gọi format() với [[level]] [formatBold(content)]
  • main.dart: Nhập tệp nhắn tin và minh họa cách cả hai loại tin nhắn có được khả năng định dạng từ mixin:
    • Tạo một TextMessage với người gửi là 'Alice'
    • Tạo một AlertMessage với cấp độ là 'WARNING'
    • Gọi send('Hello there!') trên tin nhắn văn bản
    • Gọi alert('System overload') trên tin nhắn cảnh báo

Mixin của bạn cho thấy mixin có thể chứa thuộc tính với giá trị mặc định, getter tính toán giá trị và nhiều phương thức có thể gọi lẫn nhau. Cả hai lớp tin nhắn đều có được toàn bộ chức năng này chỉ bằng cách sử dụng từ khóa with.

Đầu ra dự kiến:

>>> | Alice: Hello there!
>>> | [WARNING] **System overload**

Tự làm thử

import 'messaging.dart';

void main() {
  // TODO: Tạo TextMessage với người gửi là 'Alice'
  
  // TODO: Tạo AlertMessage với mức là 'WARNING'
  
  // TODO: Gọi send('Hello there!') trên tin nhắn văn bản
  
  // TODO: Gọi alert('System overload') trên tin nhắn cảnh báo
}
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