Menu
CoddyTech

Giới thiệu về 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 50 trên 110.

Bạn đã học rằng Dart chỉ cho phép kế thừa một lớp. Dù có thể triển khai nhiều giao diện, bạn vẫn phải tự viết toàn bộ code. Nhưng nếu bạn muốn chia sẻ phần code triển khai thực tế giữa nhiều lớp không liên quan thì sao? Đây là lúc mixin (mixin) phát huy tác dụng.

Mixin là một cách để tái sử dụng code trong nhiều hệ phân cấp lớp. Hãy hình dung nó như một tập hợp các phương thức và thuộc tính mà bạn có thể “trộn vào” bất kỳ lớp nào, giúp lớp đó có thêm khả năng mà không cần dùng đến kế thừa.

mixin Swimming {
  void swim() {
    print('Swimming through the water');
  }
}

class Duck with Swimming {
  void quack() {
    print('Quack!');
  }
}

class Fish with Swimming {
  void blowBubbles() {
    print('Blub blub');
  }
}

void main() {
  var duck = Duck();
  duck.quack();
  duck.swim();  // Từ mixin
  
  var fish = Fish();
  fish.swim();  // Cùng cách triển khai, khác lớp
}

Hãy chú ý đến từ khóa with. Đây là cách bạn áp dụng một mixin cho lớp. Khác với implements, bạn không cần tự viết phương thức. Mixin cung cấp đoạn code thực tế, và lớp của bạn tự động có chức năng đó.

Mixin giải quyết một vấn đề thực tế: Duck và Fish không có quan hệ kế thừa, nhưng cả hai đều cần khả năng bơi. Với mixin, bạn viết code một lần rồi dùng lại ở bất cứ đâu cần đến.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống nhạc cụ để tìm hiểu cách mixin giúp bạn chia sẻ hành vi giữa các lớp không liên quan với nhau. Bạn sẽ tạo một mixin cung cấp chức năng lên dây, rồi áp dụng nó cho các nhạc cụ khác nhau không có quan hệ kế thừa.

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

  • instruments.dart: Định nghĩa mixin và các lớp nhạc cụ tại đây:
    • Một mixin Tunable có phương thức tune() in ra Tuning the instrument... và phương thức checkTuning() in ra Tuning is perfect!
    • Một lớp Guitar sử dụng mixin Tunable. Thêm thuộc tính String brand cùng hàm khởi tạo. Thêm phương thức strum() in ra [brand] guitar strumming chords
    • Một lớp Piano cũng sử dụng mixin Tunable. Thêm thuộc tính int keys cùng hàm khởi tạo. Thêm phương thức play() in ra Playing [keys]-key piano
  • main.dart: Nhập tệp nhạc cụ và minh họa cách cả hai nhạc cụ không liên quan đều có khả năng lên dây nhờ cùng một mixin:
    • Tạo một Guitar có nhãn hiệu 'Fender'
    • Tạo một Piano có 88 phím
    • Với guitar: gọi tune(), rồi strum(), sau đó checkTuning()
    • In ra một dòng trống
    • Với piano: gọi tune(), rồi play(), sau đó checkTuning()

Hãy để ý rằng Guitar và Piano là hai nhạc cụ hoàn toàn khác nhau, không có quan hệ kế thừa, nhưng cả hai đều có cùng các phương thức lên dây nhờ mixin Tunable. Bạn chỉ cần viết code lên dây một lần, rồi cả hai lớp đều có thể sử dụng code đó với từ khóa with.

Đầu ra dự kiến:

Tuning the instrument...
Fender guitar strumming chords
Tuning is perfect!

Tuning the instrument...
Playing 88-key piano
Tuning is perfect!

Tự làm thử

import 'instruments.dart';

void main() {
  // TODO: Tạo một Guitar có thương hiệu 'Fender'
  
  // TODO: Tạo một Piano có 88 phím
  
  // TODO: Với đàn guitar, gọi tune(), rồi strum(), sau đó checkTuning()
  
  // TODO: In ra một dòng trống
  
  // TODO: Với đàn piano, gọi tune(), rồi play(), sau đó checkTuning()
}
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