Tworzenie domieszek
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 51 z 110.
Skoro już wiesz, czym są miksy, przyjrzyjmy się, jak prawidłowo je tworzyć. Miks deklaruje się za pomocą słowa kluczowego mixin zamiast class.
mixin Logging {
void log(String message) {
print('[LOG] $message');
}
void logError(String error) {
print('[ERROR] $error');
}
}Domieszki mogą zawierać metody, właściwości, a nawet gettery i settery — tak jak klasy. Obowiązuje jednak jedna ważna zasada: domieszki nie mogą mieć konstruktorów. Ponieważ domieszki są przeznaczone do „domieszania”, a nie do bezpośredniego tworzenia ich instancji, nie potrzebują logiki inicjalizacji.
mixin Timestamped {
DateTime createdAt = DateTime.now();
String get formattedTime => createdAt.toString();
void printTimestamp() {
print('Created at: $formattedTime');
}
}
class Document with Timestamped {
String title;
Document(this.title);
}
void main() {
var doc = Document('Report');
doc.printTimestamp(); // Używa metody z miksinu
print(doc.createdAt); // Używa właściwości z miksinu
}Gdy zastosujesz miksin za pomocą with, wszystkie jego składowe stają się częścią Twojej klasy. Klasa może korzystać z nich bezpośrednio, podobnie jak każdy kod, który ma instancję tej klasy. Dzięki temu miksiny są przejrzystym sposobem dodawania funkcjonalności wielokrotnego użytku bez złożoności hierarchii dziedziczenia.
Wyzwanie
ŁatwyZbudujmy system wiadomości, który pokaże, jak tworzyć miksy z metodami, właściwościami i getterami. Zaprojektujesz miks dodający możliwości formatowania różnym typom wiadomości.
Podzielisz kod na dwa pliki:
messaging.dart: Zdefiniuj tutaj swój miks i klasy wiadomości:- Miks
Formattable, który zawiera:- Właściwość
String prefixzainicjalizowaną wartością'>>>' - Getter
separator, który zwraca' | ' - Metodę
format(String text), która zwraca ciąg[prefix][separator][text] - Metodę
formatBold(String text), która zwraca**[text]**
- Właściwość
- Klasę
TextMessage, która używa miksuFormattable. Dodaj właściwośćString senderi konstruktor. Uwzględnij metodęsend(String content), która wyświetla wynik wywołaniaformat()z[sender]: [content] - Klasę
AlertMessage, która również używa miksuFormattable. Dodaj właściwośćString leveli konstruktor. Uwzględnij metodęalert(String content), która wyświetla wynik wywołaniaformat()z[[level]] [formatBold(content)]
- Miks
main.dart: Zaimportuj plik z wiadomościami i pokaż, jak oba typy wiadomości zyskują możliwości formatowania dzięki miksowi:- Utwórz
TextMessagez nadawcą'Alice' - Utwórz
AlertMessagez poziomem'WARNING' - Wywołaj
send('Hello there!')dla wiadomości tekstowej - Wywołaj
alert('System overload')dla wiadomości alertowej
- Utwórz
Twój miks pokazuje, że miksy mogą zawierać właściwości z wartościami domyślnymi, gettery obliczające wartości oraz wiele metod, które mogą nawet wywoływać się nawzajem. Obie klasy wiadomości zyskują całą tę funkcjonalność po prostu dzięki użyciu słowa kluczowego with.
Oczekiwany wynik:
>>> | Alice: Hello there!
>>> | [WARNING] **System overload**Spróbuj swoich sił
import 'messaging.dart';
void main() {
// TODO: Utwórz TextMessage z nadawcą 'Alice'
// TODO: Utwórz AlertMessage z poziomem 'WARNING'
// TODO: Wywołaj send('Hello there!') na wiadomości tekstowej
// TODO: Wywołaj alert('System overload') na wiadomości alarmowej
}
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