Wprowadzenie do bezpieczeństwa wartości null
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 23 z 110.
Jednym z najczęstszych źródeł błędów w programowaniu jest próba użycia wartości, która nie istnieje. W Dart ten szczególny „brak wartości” jest reprezentowany przez null. Funkcja bezpieczeństwa wartości null w Dart pomaga wychwycić te błędy, zanim kod zostanie uruchomiony.
Bez bezpieczeństwa null każda zmienna może potencjalnie mieć wartość null, co prowadzi do awarii w czasie wykonywania, gdy próbujesz jej użyć:
// W starszych wersjach Dart (bez ochrony przed null)
String name; // Może mieć wartość null!
print(name.length); // Program ulegnie awarii, jeśli name ma wartość nullPrzy włączonym bezpieczeństwie nullowalności (Dart 2.12+) kompilator rozróżnia zmienne, które mogą przechowywać wartość null, od tych, które nie mogą. Domyślnie zmienne są nienullowalne — zawsze muszą zawierać prawidłową wartość:
String name = 'Alice'; // Musi mieć wartość
print(name.length); // Bezpieczne — name nigdy nie ma wartości nullKompilator odmówi skompilowania kodu, w którym zmienna nieprzyjmująca wartości null może mieć wartość null. Dzięki temu błędy są wykrywane podczas kompilacji, a nie w czasie wykonywania, co zwiększa niezawodność Twoich programów. W kolejnych lekcjach dowiesz się, jak deklarować typy dopuszczające wartość null, gdy naprawdę ich potrzebujesz, oraz poznasz operatory, które Dart udostępnia do bezpiecznej pracy z wartościami, które potencjalnie mogą być null.
Wyzwanie
ŁatwyZbudujmy prosty system wizytówek kontaktowych, który pokazuje, jak ważne są zmienne nieprzyjmujące wartości null. Stworzysz system, w którym każdy kontakt musi zawierać prawidłowe, gwarantowane informacje.
Podzielisz kod na dwa pliki:
contact.dart: Zdefiniuj klasęContact, która reprezentuje informacje kontaktowe danej osoby. Ponieważ korzystamy z bezpieczeństwa null, każde pole musi mieć prawidłową wartość — brakujących danych nie dopuszczamy! Twoja klasa powinna zawierać:String firstName— imię kontaktuString lastName— nazwisko kontaktuString email— adres e-mail kontaktuint phoneDigits— liczbę cyfr w numerze telefonu- Konstruktor przyjmujący wszystkie cztery wartości
- Getter
fullName, który zwraca imię i nazwisko połączone spacją - Metodę
displayCard(), która wyświetla informacje o kontakcie
main.dart: Zaimportuj klasę kontaktu i utwórz dwa kontakty, aby pokazać, że wszystkie pola mają zagwarantowane wartości:- Utwórz kontakt o imieniu
'Emma', nazwisku'Wilson', adresie e-mail'emma@mail.com'i liczbie cyfr w numerze telefonu10 - Utwórz kontakt o imieniu
'James', nazwisku'Brown', adresie e-mail'james@work.com'i liczbie cyfr w numerze telefonu11 - Wywołaj
displayCard()dla każdego kontaktu w podanej wyżej kolejności
- Utwórz kontakt o imieniu
Metoda displayCard() powinna wyświetlać dane dokładnie w tym formacie:
--- Contact Card ---
Name: [fullName]
Email: [email]
Phone digits: [phoneDigits]Zauważ, że każda zmienna musi zostać zainicjalizowana rzeczywistą wartością — tak działa bezpieczeństwo null! Kompilator gwarantuje, że gdy uzyskasz dostęp do fullName, email lub dowolnego innego pola, będzie ono zawsze zawierać prawidłowe dane.
Oczekiwany wynik:
--- Contact Card ---
Name: Emma Wilson
Email: emma@mail.com
Phone digits: 10
--- Contact Card ---
Name: James Brown
Email: james@work.com
Phone digits: 11Spróbuj swoich sił
import 'contact.dart';
void main() {
// TODO: Utwórz pierwszy kontakt z następującymi danymi:
// - imię: 'Emma'
// - nazwisko: 'Wilson'
// - adres e-mail: 'emma@mail.com'
// - liczba cyfr numeru telefonu: 10
// TODO: Utwórz drugi kontakt z następującymi danymi:
// - imię: 'James'
// - nazwisko: 'Brown'
// - adres e-mail: 'james@work.com'
// - liczba cyfr numeru telefonu: 11
// TODO: Wywołaj displayCard() kolejno dla każdego kontaktu
}
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