Menu
Coddy logo textTech

Polimorfizm za pomocą interfejsów

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 58 z 110.

W poprzedniej lekcji poznano polimorfizm poprzez dziedziczenie — używanie typu klasy nadrzędnej do pracy z obiektami klas potomnych. Polimorfizm działa jednak również za pośrednictwem interfejsów, a to podejście jest często bardziej elastyczne.

Gdy klasy implementują ten sam interfejs, możesz traktować je polimorficznie, nawet jeśli nie są ze sobą powiązane dziedziczeniem:

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 i Receipt to całkowicie niezwiązane ze sobą klasy — nie mają wspólnej klasy nadrzędnej. Jednak ponieważ wszystkie implementują Printable, możemy przechowywać je na tej samej liście i wywołać printDetails() dla każdej z nich.

Jest to potężne rozwiązanie, ponieważ pozwala definiować kontrakty zachowania bez narzucania hierarchii dziedziczenia. Każda klasa może implementować interfejs, niezależnie od tego, co rozszerza. Twój kod staje się bardziej modularny, ponieważ możesz dodawać nowe typy, które można drukować, bez modyfikowania istniejącego kodu — wystarczy zaimplementować interfejs.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system odtwarzacza multimediów, który pokazuje polimorfizm za pomocą interfejsów. Utworzysz interfejs definiujący, co znaczy „odtwarzalny”, a następnie zaimplementujesz kilka niezwiązanych ze sobą typów multimediów, które spełniają ten kontrakt — dzięki czemu można je obsługiwać jednolicie, mimo że nie mają wspólnej relacji dziedziczenia.

Podzielisz kod na dwa pliki:

  • media.dart: Zdefiniuj tutaj interfejs i klasy multimediów:
    • Klasa abstrakcyjna Playable z dwiema metodami abstrakcyjnymi: play() i String getMediaType()
    • Klasa Song, która implementuje Playable. Powinna mieć String title i String artist. Jej metoda play() wyświetla Playing song: [title] by [artist], a getMediaType() zwraca 'Audio'
    • Klasa Video, która implementuje Playable. Powinna mieć String title i int duration (w minutach). Jej metoda play() wyświetla Playing video: [title] ([duration] min), a getMediaType() zwraca 'Video'
    • Klasa Podcast, która implementuje Playable. Powinna mieć String title i int episode. Jej metoda play() wyświetla Playing podcast: [title] - Episode [episode], a getMediaType() zwraca 'Podcast'
    Utwórz też funkcję playAll(List<Playable> playlist), która przechodzi przez listę i dla każdego elementu wyświetla [Media Type]:, a następnie wywołuje dla tego elementu play().
  • main.dart: Zaimportuj plik z multimediami i pokaż polimorfizm oparty na interfejsie:
    • Utwórz List<Playable> zawierającą Song z tytułem 'Imagine' i wykonawcą 'John Lennon', Video z tytułem 'Dart Tutorial' i czasem trwania 15 oraz Podcast z tytułem 'Tech Talk' i numerem odcinka 42
    • Przekaż tę listę do playAll()

Zwróć uwagę, że Song, Video i Podcast nie mają wspólnej klasy nadrzędnej — to zupełnie niezwiązane ze sobą typy. Ponieważ jednak wszystkie implementują Playable, możesz przechowywać je na tej samej liście i obsługiwać jednolicie za pośrednictwem interfejsu.

Oczekiwany wynik:

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

Spróbuj swoich sił

import 'media.dart';

void main() {
  // TODO: Utwórz List<Playable> zawierającą:
  // - Song z tytułem 'Imagine' i wykonawcą 'John Lennon'
  // - Video z tytułem 'Dart Tutorial' i czasem trwania 15
  // - Podcast z tytułem 'Tech Talk' i numerem odcinka 42
  
  // TODO: Przekaż listę do playAll()
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online