Typy wyliczeniowe z metodami
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 88 z 110.
W Dart wyliczenia nie są jedynie prostymi listami stałych — mogą mieć pola, konstruktory i metody, dzięki czemu stają się potężnymi miniaturowymi klasami. Nazywa się to rozszerzonymi wyliczeniami i pozwala przypisywać zachowanie oraz dane bezpośrednio do każdej wartości wyliczenia.
enum Status {
pending('Waiting'),
approved('Accepted'),
rejected('Denied');
final String displayName;
const Status(this.displayName);
bool get isFinalized => this == approved || this == rejected;
}
void main() {
var status = Status.pending;
print(status.displayName); // Waiting
print(status.isFinalized); // false
print(Status.approved.isFinalized); // true
}Każda wartość wyliczenia wywołuje konstruktor z właściwymi dla niej argumentami. Konstruktor musi być const, a wszystkie pola muszą być final. Możesz dodać gettery i metody, które działają na danych wyliczenia lub porównują je z innymi wartościami.
Rozszerzone typy wyliczeniowe mogą również implementować interfejsy, co zapewnia im jeszcze większą elastyczność:
enum Priority implements Comparable<Priority> {
low(1),
medium(2),
high(3);
final int level;
const Priority(this.level);
@override
int compareTo(Priority other) => level.compareTo(other.level);
}
void main() {
var tasks = [Priority.high, Priority.low, Priority.medium];
tasks.sort();
print(tasks); // [Priority.low, Priority.medium, Priority.high]
}Rozszerzone typy wyliczeniowe są idealne, gdy masz ustalony zestaw wartości, z których każda wymaga powiązanych danych lub zachowania — na przykład kody statusu z komunikatami, priorytety z poziomami lub kierunki ze współrzędnymi.
Wyzwanie
ŁatwyStwórzmy system zarządzania zadaniami z wykorzystaniem rozszerzonych wyliczeń! Utworzysz wyliczenie reprezentujące różne kategorie zadań, z których każda ma własne właściwości i zachowania pomagające organizować i ustalać priorytety pracy.
Podzielisz kod na dwa pliki:
task_category.dart: Utwórz rozszerzone wyliczenie o nazwieTaskCategory, które reprezentuje różne typy zadań w projekcie. Każda kategoria powinna mieć:- Pole
String labelz czytelną dla człowieka nazwą - Pole
int priority(1 oznacza najwyższy priorytet, 3 — najniższy) - Konstruktor
const, który inicjalizuje oba pola - Cztery wartości wyliczenia:
bug(etykieta: "Bug Fix", priorytet: 1),feature(etykieta: "New Feature", priorytet: 2),documentation(etykieta: "Documentation", priorytet: 3) itesting(etykieta: "Testing", priorytet: 2) - Getter
isUrgent, który zwracatrue, jeśli priorytet wynosi 1 - Metodę
describe(), która zwraca ciąg znaków w formacie:[label] (Priority: [priority])
Comparable<TaskCategory>, aby można było sortować zadania według priorytetu (niższa liczba priorytetu oznacza wcześniejszą pozycję).- Pole
main.dart: Zaimportuj wyliczenie kategorii zadań i zademonstruj jego możliwości:- Utwórz listę zawierającą wszystkie cztery kategorie zadań w następującej kolejności:
feature,bug,documentation,testing - Wypisz opis każdej kategorii za pomocą metody
describe(), po jednym w każdym wierszu - Wypisz pusty wiersz
- Posortuj listę według priorytetu i wypisz
After sorting by priority: - Wypisz etykietę każdej posortowanej kategorii, po jednej w każdym wierszu
- Wypisz pusty wiersz
- Wypisz
Urgent tasks: - Przejdź w pętli przez pierwotną kolejność (
feature,bug,documentation,testing) i wypisz tylko etykiety kategorii, dla którychisUrgentma wartość true
- Utwórz listę zawierającą wszystkie cztery kategorie zadań w następującej kolejności:
To wyzwanie łączy funkcje rozszerzonych wyliczeń: pola, konstruktory, gettery, metody i implementowanie interfejsów — wszystko współdziała, tworząc użyteczny system kategoryzowania zadań!
Oczekiwany wynik:
New Feature (Priority: 2)
Bug Fix (Priority: 1)
Documentation (Priority: 3)
Testing (Priority: 2)
After sorting by priority:
Bug Fix
New Feature
Testing
Documentation
Urgent tasks:
Bug FixSpróbuj swoich sił
import 'task_category.dart';
void main() {
// TODO: Utwórz listę zawierającą wszystkie cztery kategorie zadań w tej kolejności:
// feature, bug, documentation, testing
// TODO: Wypisz opis każdej kategorii za pomocą describe(), po jednym w wierszu
// TODO: Wypisz pusty wiersz
// TODO: Posortuj listę według priorytetu
// TODO: Wypisz "After sorting by priority:"
// TODO: Wypisz etykietę każdej kategorii z posortowanej listy, po jednej w wierszu
// TODO: Wypisz pusty wiersz
// TODO: Wypisz "Urgent tasks:"
// TODO: Przejdź przez kategorie w pierwotnej kolejności (feature, bug, documentation, testing)
// i wypisz tylko etykiety kategorii, dla których isUrgent ma wartość true
}
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