Menu
Coddy logo textTech

Interfejsy niejawne

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

Ponieważ każda klasa w Dart automatycznie definiuje interfejs, możesz użyć dowolnej klasy jako interfejsu — nawet klasy konkretnej z pełną implementacją. To właśnie nazywamy interfejsem niejawnym.

Rozważ klasę z właściwościami i metodami:

class Logger {
  String prefix = '[LOG]';
  
  void log(String message) {
    print('$prefix $message');
  }
  
  void clear() {
    print('Clearing logs...');
  }
}

Gdy inna klasa implementuje Logger, musi zapewnić własną implementację wszystkiego — w tym właściwości prefix:

class FileLogger implements Logger {
  @override
  String prefix = '[FILE]';
  
  @override
  void log(String message) {
    print('$prefix Writing to file: $message');
  }
  
  @override
  void clear() {
    print('Deleting log file...');
  }
}

Oto kluczowy wniosek: gdy używasz implements, mówisz: „moja klasa będzie miała taki sam kształt” — te same metody i właściwości. Nie dziedziczysz żadnego kodu, konstruktorów ani wartości domyślnych. Obiecujesz jedynie dopasować się do struktury interfejsu.

Dzięki temu niejawne interfejsy są przydatne do tworzenia wymiennych komponentów. Kod, który oczekuje obiektu Logger, może współpracować z każdą klasą implementującą jego interfejs, niezależnie od tego, jak działa ona wewnętrznie.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system powiadomień, który pokazuje, jak klasy konkretne mogą pełnić rolę niejawnych interfejsów. Utworzysz bazową klasę powiadomienia, a następnie zaimplementujesz ją w zupełnie inny sposób, pokazując, że implements wymaga samodzielnego dostarczenia wszystkich składowych.

Podzielisz kod na dwa pliki:

  • notification.dart: Zdefiniuj tutaj klasy powiadomień:
    • Klasę Notification z właściwością String channel ustawioną na 'default', metodą send(String message), która wyświetla [channel]: [message], oraz metodą getStatus(), która zwraca ciąg znaków 'Notification ready'
    • Klasę EmailNotification, która implementuje Notification. Ponieważ używasz implements, musisz podać własną właściwość channel (ustaw ją na 'email'), własną metodę send(), która wyświetla Sending email: [message], oraz własną metodę getStatus(), która zwraca 'Email service active'
    • Klasę PushNotification, która implementuje Notification. Ustaw jej channel na 'push', spraw, by send() wyświetlała Push alert: [message], a metoda getStatus() zwracała 'Push service connected'
  • main.dart: Zaimportuj plik z powiadomieniami i pokaż, jak różne klasy mogą implementować ten sam niejawny interfejs, uzyskując zupełnie różne zachowania:
    • Utwórz obiekt EmailNotification i obiekt PushNotification
    • Dla każdego powiadomienia wyświetl jego status za pomocą getStatus(), a następnie wywołaj send() z wiadomością 'Hello World'
    • Wyświetl pustą linię między tymi dwoma powiadomieniami

Pamiętaj: gdy używasz implements, nie dziedziczysz żadnego kodu z Notification. Obiecujesz jedynie, że twoja klasa będzie miała taki sam kształt — te same właściwości i metody. Każda klasa implementująca zapewnia własną, kompletną implementację.

Oczekiwany wynik:

Email service active
Sending email: Hello World

Push service connected
Push alert: Hello World

Spróbuj swoich sił

import 'notification.dart';

void main() {
  // TODO: Utwórz instancję EmailNotification
  
  // TODO: Wyświetl status powiadomienia e-mail za pomocą getStatus()
  
  // TODO: Wyślij wiadomość 'Hello World' za pomocą powiadomienia e-mail
  
  // TODO: Wyświetl pustą linię
  
  // TODO: Utwórz instancję PushNotification
  
  // TODO: Wyświetl status powiadomienia push za pomocą getStatus()
  
  // TODO: Wyślij wiadomość 'Hello World' za pomocą powiadomienia push
  
}
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