Menu
Coddy logo textTech

Sicurezza dei valori null nelle classi

Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 28 di 110.

Quando progetti le classi, devi decidere quali campi sono obbligatori e quali facoltativi. La sicurezza rispetto ai valori null influisce sul modo in cui dichiari le variabili di istanza e scrivi i costruttori.

I campi non nullable devono essere inizializzati prima che venga eseguito il corpo del costruttore. Puoi farlo tramite liste di inizializzazione, parametri del costruttore o valori predefiniti:

class User {
  String name;           // Deve essere inizializzato
  String? bio;           // Facoltativo - può essere null
  int age = 0;           // Ha un valore predefinito
  
  User(this.name);       // name viene inizializzato tramite un parametro
}

Per i campi nullable, puoi lasciarli non inizializzati, poiché il valore predefinito è null. Questo è utile per i dati facoltativi:

class Product {
  String title;
  String? description;   // Descrizione facoltativa del prodotto
  double? discount;      // Nessuno sconto per impostazione predefinita
  
  Product(this.title);
}

var item = Product('Laptop');
print(item.description);  // null
print(item.discount);     // null

Quando accedi ai campi nullable, usa gli operatori null-aware che hai imparato:

class Order {
  String id;
  User? customer;
  
  Order(this.id);
  
  String getCustomerName() {
    return customer?.name ?? 'Guest';
  }
}

La parola chiave required nei parametri con nome assicura che chi chiama fornisca i valori essenziali:

class Account {
  String email;
  String? phone;
  
  Account({required this.email, this.phone});
}

var acc = Account(email: 'test@mail.com');  // phone è facoltativo

Scegliendo con criterio tra campi nullable e non nullable, crei classi che comunicano chiaramente quali dati sono essenziali e quali facoltativi.

challenge icon

Sfida

Facile

Creiamo un sistema di prenotazione per un hotel che dimostri come progettare classi con un'attenta combinazione di campi obbligatori e facoltativi usando la sicurezza rispetto ai valori null.

Organizzerai il codice in due file:

  • reservation.dart: definisci una classe Reservation che rappresenta una prenotazione alberghiera. Ogni prenotazione richiede alcune informazioni essenziali, ma alcuni dettagli sono extra facoltativi che gli ospiti possono fornire o meno. La tua classe dovrebbe avere:
    • Un String guestName non nullable: ogni prenotazione deve avere il nome di un ospite
    • Un int roomNumber non nullable: a ogni prenotazione deve essere assegnata una camera
    • Un int nights non nullable con valore predefinito 1: il soggiorno minimo è di una notte
    • Un String? specialRequests nullable: gli ospiti possono avere richieste speciali
    • Un DateTime? checkInTime nullable: l'ora esatta di arrivo potrebbe non essere nota
    • Un costruttore che usa parametri con nome e required per guestName e roomNumber, mentre nights dovrebbe essere facoltativo e avere il suo valore predefinito
    • Un metodo getRequestsSummary() che restituisce le richieste speciali, se specificate, oppure 'No special requests' usando l'operatore ??
    • Un metodo getArrivalInfo() che restituisce la rappresentazione in stringa dell'ora di check-in usando ?., oppure null se non è impostata
    • Un metodo printConfirmation() che visualizza i dettagli della prenotazione
  • main.dart: importa la classe della prenotazione e crea prenotazioni che mostrino diverse combinazioni di dati obbligatori e facoltativi:
    • Crea una prenotazione per l'ospite 'Sarah Johnson' nella camera 101 per 3 notti, con richieste speciali 'Late checkout' e ora di check-in impostata su DateTime(2024, 6, 15, 14, 30)
    • Crea una prenotazione per l'ospite 'Mike Chen' nella camera 205 (usa il numero predefinito di notti), impostando solo le richieste speciali su 'Extra pillows'
    • Crea una prenotazione per l'ospite 'Emma Davis' nella camera 310 per 2 notti (lascia entrambi i campi facoltativi impostati su null)
    • Per ogni prenotazione, nell'ordine, chiama printConfirmation(), poi stampa Arrival: [result] usando getArrivalInfo()

Il metodo printConfirmation() dovrebbe stampare in questo formato:

=== Reservation Confirmed ===
Guest: [guestName]
Room: [roomNumber]
Nights: [nights]
Requests: [getRequestsSummary()]

Output previsto:

=== Reservation Confirmed ===
Guest: Sarah Johnson
Room: 101
Nights: 3
Requests: Late checkout
Arrival: 2024-06-15 14:30:00.000
=== Reservation Confirmed ===
Guest: Mike Chen
Room: 205
Nights: 1
Requests: Extra pillows
Arrival: null
=== Reservation Confirmed ===
Guest: Emma Davis
Room: 310
Nights: 2
Requests: No special requests
Arrival: null

Provalo tu

import 'reservation.dart';

void main() {
  // TODO: Crea una prenotazione per 'Sarah Johnson'
  // Camera 101, 3 notti, richieste speciali: 'Late checkout'
  // Orario di check-in: DateTime(2024, 6, 15, 14, 30)
  
  // TODO: Crea una prenotazione per 'Mike Chen'
  // Camera 205, usa il numero predefinito di notti, richieste speciali: 'Extra pillows'
  // Nessun orario di check-in specificato
  
  // TODO: Crea una prenotazione per 'Emma Davis'
  // Camera 310, 2 notti, nessuna richiesta speciale, nessun orario di check-in
  
  // TODO: Per ogni prenotazione, nell'ordine:
  // 1. Chiama printConfirmation()
  // 2. Stampa 'Arrival: [result]' usando getArrivalInfo()
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Dart online