Menu
CoddyTech

Đa hình qua giao diện

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

Trong bài học trước, bạn đã tìm hiểu về tính đa hình (polymorphism) thông qua kế thừa (inheritance), tức là dùng kiểu của lớp cha để làm việc với các đối tượng thuộc lớp con. Tính đa hình cũng hoạt động thông qua giao diện (interface), và cách này thường linh hoạt hơn.

Khi các lớp triển khai cùng một giao diện, bạn có thể xử lý chúng theo cách đa hình ngay cả khi chúng không có quan hệ kế thừa:

abstract class Printable {
  void printDetails();
}

class Invoice implements Printable {
  @override
  void printDetails() => print('Invoice #1234');
}

class Report implements Printable {
  @override
  void printDetails() => print('Monthly Report');
}

class Receipt implements Printable {
  @override
  void printDetails() => print('Receipt for purchase');
}

void printAll(List<Printable> items) {
  for (var item in items) {
    item.printDetails();
  }
}

void main() {
  var documents = [Invoice(), Report(), Receipt()];
  printAll(documents);
}

Invoice, Report và Receipt là các lớp hoàn toàn không liên quan, chúng không có lớp cha chung. Tuy nhiên, vì tất cả đều triển khai Printable, chúng ta có thể lưu chúng trong cùng một danh sách và gọi printDetails() trên từng lớp.

Cách này rất hữu ích vì cho phép bạn xác định các hợp đồng về hành vi mà không cần áp đặt hệ thống phân cấp kế thừa. Bất kỳ lớp nào cũng có thể triển khai một giao diện, bất kể lớp đó kế thừa lớp nào. Code của bạn trở nên mô-đun hơn vì bạn có thể thêm các kiểu có thể in mới mà không cần sửa code hiện có, chỉ cần triển khai giao diện.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống phát đa phương tiện để minh họa tính đa hình thông qua giao diện. Bạn sẽ tạo một giao diện định nghĩa thế nào là “có thể phát”, sau đó triển khai một số loại đa phương tiện không liên quan với nhau, tất cả đều đáp ứng giao diện này. Nhờ vậy, chúng có thể được xử lý thống nhất dù không có quan hệ kế thừa.

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

  • media.dart: Định nghĩa giao diện và các lớp đa phương tiện tại đây:
    • Một lớp trừu tượng Playable với hai phương thức trừu tượng: play() và String getMediaType()
    • Một lớp Song triển khai Playable. Lớp này cần có String title và String artist. Phương thức play() in ra Playing song: [title] by [artist], còn getMediaType() trả về 'Audio'
    • Một lớp Video triển khai Playable. Lớp này cần có String title và int duration (tính bằng phút). Phương thức play() in ra Playing video: [title] ([duration] min), còn getMediaType() trả về 'Video'
    • Một lớp Podcast triển khai Playable. Lớp này cần có String title và int episode. Phương thức play() in ra Playing podcast: [title] - Episode [episode], còn getMediaType() trả về 'Podcast'
    Đồng thời, hãy tạo hàm playAll(List<Playable> playlist) để duyệt qua danh sách và in ra [Media Type]: cho từng phần tử, sau đó gọi play() trên phần tử đó.
  • main.dart: Nhập tệp đa phương tiện và minh họa tính đa hình dựa trên giao diện:
    • Tạo một List<Playable> chứa một Song có tiêu đề 'Imagine' và nghệ sĩ 'John Lennon', một Video có tiêu đề 'Dart Tutorial' và thời lượng 15, cùng một Podcast có tiêu đề 'Tech Talk' và số tập 42
    • Truyền danh sách này vào playAll()

Hãy chú ý rằng Song, Video và Podcast không có lớp cha chung, chúng hoàn toàn không liên quan với nhau. Tuy nhiên, vì tất cả đều triển khai Playable, bạn có thể lưu chúng trong cùng một danh sách và xử lý thống nhất thông qua giao diện.

Đầu ra dự kiến:

Audio:
Playing song: Imagine by John Lennon
Video:
Playing video: Dart Tutorial (15 min)
Podcast:
Playing podcast: Tech Talk - Episode 42

Tự làm thử

import 'media.dart';

void main() {
  // TODO: Tạo một List<Playable> gồm:
  // - Một Song có tiêu đề 'Imagine' và nghệ sĩ 'John Lennon'
  // - Một Video có tiêu đề 'Dart Tutorial' và thời lượng 15
  // - Một Podcast có tiêu đề 'Tech Talk' và số tập 42
  
  // TODO: Truyền danh sách vào playAll()
}
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