Interfejsy w Dart
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 45 z 110.
W przeciwieństwie do wielu języków, które mają dedykowane słowo kluczowe interface, Dart podchodzi do tego inaczej. W Dart każda klasa automatycznie definiuje interfejs. Interfejs ten składa się ze wszystkich publicznych elementów (metod i właściwości) zadeklarowanych przez klasę.
Gdy chcesz, aby klasa zobowiązała się do zapewnienia określonej funkcjonalności bez dziedziczenia implementacji, używasz słowa kluczowego implements:
class Printer {
void printDocument(String content) {
print('Printing: $content');
}
}
class Scanner {
void scan() {
print('Scanning document');
}
}
// MultiFunctionDevice musi implementować WSZYSTKIE metody z obu klas
class MultiFunctionDevice implements Printer, Scanner {
@override
void printDocument(String content) {
print('MFD printing: $content');
}
@override
void scan() {
print('MFD scanning');
}
}Kluczowa różnica w porównaniu z extends polega na tym, że implements nie dziedziczy żadnego kodu. Musisz samodzielnie zaimplementować każdą metodę i właściwość zdefiniowaną w interfejsie. To umowa — obiecujesz, że Twoja klasa będzie mieć te możliwości, ale sam decydujesz, jak dokładnie będą działać.
To podejście zapewnia Dart elastyczność. Możesz używać klas abstrakcyjnych, gdy chcesz zdefiniować interfejsy bez implementacji, albo używać zwykłych klas jako interfejsów, gdy ma to sens. W następnej lekcji dokładniej poznasz działanie koncepcji „niejawnego interfejsu”.
Wyzwanie
ŁatwyZbudujmy system odtwarzacza multimediów, który pokaże, jak działa słowo kluczowe implements w Dart. Utworzysz klasy pełniące rolę interfejsów, a następnie zaimplementujesz je w jednym urządzeniu łączącym wiele funkcji.
Podzielisz swój kod na dwa pliki:
media.dart: Zdefiniuj tutaj klasy interfejsów i klasę, która je implementuje:- Klasę
AudioPlayerz metodąplayAudio(String track), która wyświetlaPlaying audio: [track] - Klasę
VideoPlayerz metodąplayVideo(String title), która wyświetlaPlaying video: [title] - Klasę
SmartTV, która implementuje zarównoAudioPlayer, jak iVideoPlayer. Ponieważimplementsnie dziedziczy żadnego kodu, musisz samodzielnie zaimplementować obie metody. Twoja klasaSmartTVpowinna wyświetlaćSmartTV audio: [track]dla dźwięku iSmartTV video: [title]dla wideo
- Klasę
main.dart: Zaimportuj plik multimedialny i pokaż, jak jedna klasa może implementować wiele interfejsów:- Utwórz instancję klasy
SmartTV - Wywołaj
playAudio('Jazz Collection') - Wywołaj
playVideo('Nature Documentary')
- Utwórz instancję klasy
Zwróć uwagę, że SmartTV musi samodzielnie zaimplementować każdą metodę z obu interfejsów — nie dziedziczy oryginalnych implementacji z klas AudioPlayer ani VideoPlayer. To kluczowa różnica między implements a extends.
Oczekiwany wynik:
SmartTV audio: Jazz Collection
SmartTV video: Nature DocumentarySpróbuj swoich sił
import 'media.dart';
void main() {
// TODO: Utwórz instancję SmartTV
// TODO: Wywołaj playAudio('Jazz Collection')
// TODO: Wywołaj playVideo('Nature Documentary')
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP
Pliki zewnętrzneBiblioteki i importyWprowadzenie do OOPKlasy a obiektySłowo kluczowe thisMetodyZmienne instancjiPodstawy konstruktorówPowtórka – prosty kalkulator4Bezpieczeństwo wartości null
Wprowadzenie do bezpieczeństwa wartości nullTypy dopuszczające null i niedopuszczające nullOperatory ? i !Słowo kluczowe late a bezpieczeństwo wartości nullOperatory uwzględniające nullBezpieczeństwo wartości null w klasachPodsumowanie — system profili użytkowników7Klasy abstrakcyjne i interfejsy
Klasy abstrakcyjneMetody abstrakcyjneInterfejsy w DartInterfejsy niejawneImplementowanie a rozszerzanieWiele interfejsówPowtórka — kalkulator kształtów10Kolekcje i typy generyczne
Przegląd List, Set i MapKolekcje bezpieczne typowoKlasy generyczneMetody generyczneOgraniczenia typów generycznychIterable i IteratorPowtórka — generyczne przechowywanie danych13Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieMetody rozszerzająceKlasy wywoływalneKlasy zapieczętowane (Dart 3)Rekordy (Dart 3)Wzorce i dopasowywanie (3.0)Typy wyliczeniowe z metodami16Projekt: Zarządzanie biblioteką
Omówienie projektuKlasy książek i użytkowników2Konstruktory w Dart
Konstruktor domyślnyKonstruktory nazwaneListy inicjalizująceKonstruktory stałeKonstruktory fabryczneKonstruktory przekierowującePodsumowanie — budowanie kształtów5Hermetyzacja
Elementy publiczne a prywatneKonwencja prefiksu _Prywatność na poziomie bibliotekiGettery i settery — szczegółowoUkrywanie informacjiPodsumowanie — dane uczniów8Domieszki
Wprowadzenie do domieszekTworzenie domieszekKorzystanie z wielu domieszekSłowo kluczowe on w domieszkachDomieszka a dziedziczenieDomieszka a interfejsPodsumowanie – system zwierząt11Metody specjalne
Nadpisanie toString()Nadpisanie hashCode i ==Interfejs ComparableMetoda call()Nadpisanie noSuchMethodPodsumowanie — własna kolekcja14Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec Strategy3Właściwości klas
Elementy instancji a elementy statycznePola final i constZmienne inicjalizowane z opóźnieniemMetody i pola statyczneGettery i setteryPowtórzenie – menedżer kont bankowych6Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superPrzesłanianie metodAdnotacja @overrideSłowo kluczowe final dla klasKonstruktory i dziedziczeniePowtórzenie – hierarchia pracowników9Polimorfizm
Podstawy polimorfizmuPolimorfizm za pomocą interfejsówSprawdzanie typu w czasie działaniaOperatory is i asSłowo kluczowe covariantPodsumowanie — procesor płatnościPoćwicz samodzielnie: Kompilator Dart online