Metody rozszerzające
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 83 z 110.
Czasami chcesz dodać funkcjonalność do klasy, której nie jesteś właścicielem — takiej jak wbudowane typy Dart String lub int. Nie możesz modyfikować ich kodu źródłowego, a dziedziczenie nie pomoże w przypadku klas finalnych. Właśnie w takich sytuacjach przydają się metody rozszerzające.
Rozszerzenia pozwalają dodawać nowe metody do istniejących typów bez ich modyfikowania ani tworzenia podklas:
extension StringExtras on String {
String reverse() {
return split('').reversed.join('');
}
bool get isPalindrome {
var cleaned = toLowerCase().replaceAll(' ', '');
return cleaned == cleaned.split('').reversed.join('');
}
}
void main() {
print('hello'.reverse()); // olleh
print('radar'.isPalindrome); // true
}Składnia ma postać extension ExtensionName on Type. Wewnątrz definiujesz metody i gettery tak jak w zwykłej klasie. Po zdefiniowaniu te metody są dostępne we wszystkich instancjach tego typu, jakby były wbudowane.
Rozszerzenia działają na dowolnym typie, w tym na własnych klasach i typach generycznych:
extension IntExtras on int {
int squared() => this * this;
}
extension ListExtras<T> on List<T> {
T? get secondOrNull => length >= 2 ? this[1] : null;
}
void main() {
print(5.squared()); // 25
print([1, 2, 3].secondOrNull); // 2
}Zauważ, że wewnątrz rozszerzenia this odnosi się do instancji, na której wywoływana jest metoda. Rozszerzenia to przejrzysty sposób na wzbogacanie istniejących typów przy zachowaniu uporządkowanego i czytelnego kodu.
Wyzwanie
ŁatwyUlepszmy wbudowane typy Dart, dodając do nich przydatne funkcje za pomocą metod rozszerzających! Utworzysz rozszerzenia dodające pomocne metody do typów String i List, a następnie użyjesz ich w pliku głównym.
Podzielisz swój kod na dwa pliki:
extensions.dart: Utwórz dwa rozszerzenia dodające nowe możliwości do istniejących typów:- Rozszerzenie o nazwie
StringUtilsdla typuString, zawierające:- Metodę
countVowels(), która zwraca liczbę samogłosek (a, e, i, o, u — bez rozróżniania wielkości liter) w ciągu znaków - Getter
initials, który zwraca pierwszą literę każdego słowa (podzielonego spacjami), połączone litery zapisane wielkimi literami. Na przykład"hello world"zmienia się w"HW"
- Metodę
- Rozszerzenie o nazwie
ListUtils<T>dla typuList<T>, zawierające:- Metodę
safeGet(int index), która zwraca element o podanym indeksie, jeśli istnieje, lubnull, jeśli indeks jest poza zakresem - Getter
hasMultiple, który zwracatrue, jeśli tablica zawiera więcej niż jeden element
- Metodę
- Rozszerzenie o nazwie
main.dart: Zaimportuj swoje rozszerzenia i pokaż je w działaniu:- Utwórz ciąg znaków
"Object Oriented Programming"i wypisz liczbę samogłosek w formacie:Vowels: [count] - Wypisz inicjały tego samego ciągu znaków w formacie:
Initials: [initials] - Utwórz tablicę liczb całkowitych
[10, 20, 30] - Wypisz wynik działania
safeGet(1)w formacie:Element at 1: [value] - Wypisz wynik działania
safeGet(5)w formacie:Element at 5: [value] - Wypisz informację, czy tablica zawiera wiele elementów, w formacie:
Has multiple: [true/false]
- Utwórz ciąg znaków
Pamiętaj, że wewnątrz rozszerzenia this odnosi się do instancji, na której wywoływana jest metoda. Dzięki rozszerzeniom te typy będą sprawiać wrażenie, jakby te metody były wbudowane!
Oczekiwany wynik:
Vowels: 9
Initials: OOP
Element at 1: 20
Element at 5: null
Has multiple: trueSpróbuj swoich sił
import 'extensions.dart';
void main() {
// Utwórz łańcuch znaków
String text = "Object Oriented Programming";
// TODO: Wypisz liczbę samogłosek, używając countVowels()
// Format: Samogłoski: [count]
// TODO: Wypisz inicjały, używając gettera initials
// Format: Inicjały: [initials]
// Utwórz listę liczb całkowitych
List<int> numbers = [10, 20, 30];
// TODO: Wypisz wynik safeGet(1)
// Format: Element at 1: [value]
// TODO: Wypisz wynik safeGet(5)
// Format: Element at 5: [value]
// TODO: Wypisz, czy lista ma więcej niż jeden element
// Format: Has multiple: [true/false]
}
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