Null-Sicherheit in Klassen
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 28 von 110.
Beim Entwurf von Klassen müssen Sie entscheiden, welche Felder erforderlich und welche optional sind. Die Null-Sicherheit beeinflusst, wie Sie Instanzvariablen deklarieren und Konstruktoren schreiben.
Nicht-nullbare Felder müssen initialisiert werden, bevor der Konstruktor-Body ausgeführt wird. Dies kann über Initialisierungslisten, Konstruktorparameter oder Standardwerte erfolgen:
class User {
String name; // Muss initialisiert werden
String? bio; // Optional - kann null sein
int age = 0; // Hat einen Standardwert
User(this.name); // name wird über den Parameter initialisiert
}Für Nullable-Felder können Sie diese nicht initialisiert lassen, da sie standardmäßig auf null gesetzt werden. Dies ist nützlich für optionale Daten:
class Product {
String title;
String? description; // Optionale Produktbeschreibung
double? discount; // Standardmäßig kein Rabatt
Product(this.title);
}
var item = Product('Laptop');
print(item.description); // null
print(item.discount); // nullVerwenden Sie beim Zugriff auf Nullable-Felder die Null-aware-Operatoren, die Sie gelernt haben:
class Order {
String id;
User? customer;
Order(this.id);
String getCustomerName() {
return customer?.name ?? 'Guest';
}
}Das Schlüsselwort required in benannten Parametern stellt sicher, dass Aufrufer wesentliche Werte bereitstellen:
class Account {
String email;
String? phone;
Account({required this.email, this.phone});
}
var acc = Account(email: 'test@mail.com'); // phone ist optionalDurch die bewusste Entscheidung zwischen Nullable- und Non-Nullable-Feldern erstellen Sie Klassen, die klar kommunizieren, welche Daten erforderlich und welche optional sind.
Aufgabe
EinfachLass uns ein Buchungssystem für ein Hotel erstellen, das zeigt, wie man Klassen mit einer durchdachten Mischung aus erforderlichen und optionalen Feldern mithilfe von Null-Sicherheit entwirft.
Du organisierst deinen Code in zwei Dateien:
reservation.dart: Definiere eineReservation-Klasse, die eine Hotelbuchung darstellt. Jede Reservierung benötigt bestimmte wesentliche Informationen, aber einige Angaben sind optionale Zusatzinformationen, die Gäste möglicherweise angeben oder auch nicht. Deine Klasse sollte Folgendes enthalten:- Ein nicht nullbares
String guestName– jede Reservierung muss einen Namen des Gastes haben - Ein nicht nullbares
int roomNumber– jeder Reservierung muss ein Zimmer zugewiesen werden - Ein nicht nullbares
int nightsmit dem Standardwert1– der Mindestaufenthalt beträgt eine Nacht - Ein nullable
String? specialRequests– Gäste können besondere Wünsche haben - Ein nullable
DateTime? checkInTime– die genaue Ankunftszeit ist möglicherweise nicht bekannt - Einen Konstruktor mit benannten Parametern, bei dem
requiredfürguestNameundroomNumberverwendet wird, währendnightsmit seinem Standardwert optional sein soll - Eine Methode
getRequestsSummary(), die die besonderen Wünsche zurückgibt, sofern sie angegeben wurden, oder mithilfe des'No special requests'-Operators?? - Eine Methode
getArrivalInfo(), die mithilfe von?.die String-Darstellung der Check-in-Zeit zurückgibt odernull, wenn sie nicht festgelegt wurde - Eine Methode
printConfirmation(), die die Reservierungsdetails anzeigt
- Ein nicht nullbares
main.dart: Importiere deine Reservierungsklasse und erstelle Buchungen, die verschiedene Kombinationen aus erforderlichen und optionalen Daten zeigen:- Erstelle eine Reservierung für den Gast
'Sarah Johnson'in Zimmer101für3Nächte, mit den besonderen Wünschen'Late checkout'und der aufDateTime(2024, 6, 15, 14, 30)gesetzten Check-in-Zeit - Erstelle eine Reservierung für den Gast
'Mike Chen'in Zimmer205(verwende den Standardwert für die Nächte), bei der nur die besonderen Wünsche auf'Extra pillows'gesetzt sind - Erstelle eine Reservierung für den Gast
'Emma Davis'in Zimmer310für2Nächte (lasse beide optionalen Felder auf null) - Rufe für jede Reservierung in dieser Reihenfolge
printConfirmation()auf und gib anschließendArrival: [result]mithilfe vongetArrivalInfo()aus
- Erstelle eine Reservierung für den Gast
Die Methode printConfirmation() sollte in diesem Format ausgeben:
=== Reservation Confirmed ===
Guest: [guestName]
Room: [roomNumber]
Nights: [nights]
Requests: [getRequestsSummary()]Erwartete Ausgabe:
=== 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: nullProbier es selbst
import 'reservation.dart';
void main() {
// TODO: Reservierung für 'Sarah Johnson' erstellen
// Zimmer 101, 3 Nächte, Sonderwünsche: 'Late checkout'
// Check-in-Zeit: DateTime(2024, 6, 15, 14, 30)
// TODO: Reservierung für 'Mike Chen' erstellen
// Zimmer 205, Standardanzahl an Nächten verwenden, Sonderwünsche: 'Extra pillows'
// Keine Check-in-Zeit angegeben
// TODO: Reservierung für 'Emma Davis' erstellen
// Zimmer 310, 2 Nächte, keine Sonderwünsche, keine Check-in-Zeit
// TODO: Für jede Reservierung in der Reihenfolge:
// 1. printConfirmation() aufrufen
// 2. 'Arrival: [result]' mit getArrivalInfo() ausgeben
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienBibliotheken & ImportsEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort thisMethodenInstanzvariablenGrundlagen von KonstruktorenRückblick – Einfacher Taschenrechner4Null-Sicherheit
Einführung in die Null-SicherheitNullable vs. Non-NullableDie Operatoren ? und !Late-Schlüsselwort und Null-SicherheitNull-bewusste OperatorenNull-Sicherheit in KlassenRückblick – Benutzers профilsystem7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrere InterfacesZusammenfassung – Formrechner10Collections & Generics
Übersicht über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische EinschränkungenIterable & IteratorRückblick – Generischer Speicher13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungErweiterungsmethodenAufrufbare KlassenVersiegelte Klassen (Dart 3)Records (Dart 3)Muster & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
StandardkonstruktorBenannte KonstruktorenInitialisierungslistenKonstantenkonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenRückblick – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _-Präfix-KonventionBibliotheksweite SichtbarkeitTiefergehende Getter & SetterInformationsverbergungRückblick – Studierendendaten8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas Schlüsselwort „on“ in MixinsMixin vs. VererbungMixin vs. SchnittstelleRückblick – Tiersystem11Spezielle Methoden
toString()-ÜberschreibunghashCode- & ==-ÜberschreibungComparable-Schnittstellecall()-MethodenoSuchMethod-ÜberschreibungWiederholung – Benutzerdefinierte Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFabrikmusterBeobachtermusterStrategiemuster17Abschließende Herausforderungen
E-Learning-PlattformBankingsystemSpielcharaktersystemFahrzeugvermietung3Klassen-Eigenschaften
Instanz- vs. statische MemberFinal- und Const-FelderLate-VariablenStatische Methoden und FelderGetter und SetterRückblick – Bankkontoverwaltung6Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungDie Annotation @overrideDas Schlüsselwort final für KlassenKonstruktoren und VererbungZusammenfassung – Mitarbeiterhierarchie9Polymorphismus
Grundlagen des PolymorphismusPolymorphismus über InterfacesLaufzeit-TypüberprüfungDie Operatoren is & asCovariant-SchlüsselwortZusammenfassung – ZahlungsprozessorÜbe selbstständig: Online-Dart-Compiler