Zmienne inicjalizowane z opóźnieniem
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 19 z 110.
Słowo kluczowe late informuje Dart, że zmienna, która nie dopuszcza wartości null, zostanie zainicjalizowana przed użyciem, mimo że nie przypisuje się jej wartości od razu. Jest to przydatne, gdy nie możesz zainicjalizować pola w deklaracji lub konstruktorze, ale masz pewność, że będzie miało wartość, zanim zostanie użyte.
class User {
late String username;
void initialize(String name) {
username = name;
}
void greet() {
print('Hello, $username!');
}
}
User user = User();
user.initialize('Alice');
user.greet(); // Cześć, Alice!Bez late Dart zgłosiłby, że username nie jest zainicjalizowane. Modyfikator late oznacza, że przypiszesz wartość, zanim ją odczytasz.
Kolejną zaletą late jest leniwa inicjalizacja. Zmienna late z inicjalizatorem nie obliczy swojej wartości, dopóki nie zostanie użyta po raz pierwszy:
class Config {
late String settings = loadSettings();
String loadSettings() {
print('Loading...');
return 'default';
}
}
Config config = Config();
print('Config created');
print(config.settings); // "Loading..." jest wyświetlane tutaj, a następnie "default"Metoda loadSettings() uruchamia się dopiero przy pierwszym dostępie do settings, a nie podczas tworzenia obiektu. Uważaj jednak — dostęp do zmiennej late przed jej zainicjalizowaniem powoduje błąd wykonania.
Wyzwanie
ŁatwyZbudujmy menedżera połączeń z bazą danych, który demonstruje zarówno odroczoną inicjalizację, jak i leniwą inicjalizację za pomocą zmiennych late.
Utworzysz dwa pliki, aby uporządkować swój kod:
database.dart: Zdefiniuj klasęDatabase, która symuluje połączenie z bazą danych. Twoja klasa powinna zawierać:late String connectionString, które zostanie ustawione po utworzeniu obiektulate String statusz leniwym inicjalizatorem, który wypisujeChecking connection...i zwraca'Connected'- metodę
connect(String connStr), która ustawiaconnectionStringi wypisujeConnection configured: [connectionString] - metodę
query(String sql), która wypisujeExecuting on [connectionString]: [sql] - metodę
checkStatus(), która wypisujeStatus: [status](to wywoła leniwą inicjalizację przy pierwszym wywołaniu)
main.dart: Zaimportuj swoją klasę bazy danych i zademonstruj oba zastosowanialate:- Utwórz instancję
Database - Wypisz
Database object created - Wywołaj
connect()z ciągiem połączenia'localhost:5432/mydb' - Wywołaj
query()z'SELECT * FROM users' - Wywołaj
checkStatus(), aby uruchomić leniwą inicjalizację
- Utwórz instancję
Zwróć uwagę, że connectionString jest ustawiane ręcznie po utworzeniu obiektu, podczas gdy status oblicza swoją wartość dopiero przy pierwszym dostępie.
Oczekiwany wynik:
Database object created
Connection configured: localhost:5432/mydb
Executing on localhost:5432/mydb: SELECT * FROM users
Checking connection...
Status: ConnectedSpróbuj swoich sił
import 'database.dart';
void main() {
// TODO: Utwórz instancję Database
// TODO: Wypisz 'Database object created'
// TODO: Wywołaj connect() z argumentem 'localhost:5432/mydb'
// TODO: Wywołaj query() z argumentem 'SELECT * FROM users'
// TODO: Wywołaj checkStatus(), aby uruchomić leniwą inicjalizację
}
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