Das Schlüsselwort final für Klassen
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 40 von 110.
Manchmal möchte man verhindern, dass eine Klasse erweitert wird. Das Schlüsselwort final verhindert, wenn es auf eine Klasse angewendet wird, dass andere Klassen von ihr erben.
final class DatabaseConnection {
String connectionString;
DatabaseConnection(this.connectionString);
void connect() {
print('Connected to $connectionString');
}
}
// Dies würde einen Kompilierzeitfehler verursachen:
// class CustomConnection extends DatabaseConnection { }Eine Klasse als final zu kennzeichnen ist nützlich, wenn deren Erweiterung ihr beabsichtigtes Verhalten oder ihre Sicherheitsgarantien beeinträchtigen könnte. Zum Beispiel muss eine Klasse, die sensible Ressourcen verwaltet, möglicherweise sicherstellen, dass ihre Methoden nicht auf unerwartete Weise überschrieben werden.
Dart 3 hat auch verwandte Modifikatoren eingeführt: base zwingt Unterklassen dazu, extends (nicht implements) zu verwenden, und sealed beschränkt die Vererbung auf dieselbe Bibliothek. Konzentrieren Sie sich vorerst auf final als einfachste Methode, um eine Klasse vollständig abzusperren.
Verwenden Sie final-Klassen, wenn Sie sicher sind, dass das Klassendesign abgeschlossen ist und Vererbung nur Probleme verursachen würde. Verwenden Sie es jedoch nicht zu oft – die meisten Klassen profitieren davon, für Erweiterungen offen zu bleiben.
Aufgabe
EinfachLass uns ein sicheres Konfigurationssystem erstellen, das veranschaulicht, wann und warum du verhindern möchtest, dass eine Klasse erweitert wird. Du erstellst eine finale Klasse, die Anwendungseinstellungen verwaltet und sicherstellt, dass ihr Verhalten nicht durch Vererbung verändert werden kann.
Du organisierst deinen Code in zwei Dateien:
config.dart: Definiere hier deine Konfigurationsklassen:- Eine
final class AppConfig, die nicht erweitert werden kann. Sie sollte eine EigenschaftString appNameund eine EigenschaftString version, einen Konstruktor, der beide Werte entgegennimmt, sowie eine Methodedisplay()besitzen, die[appName] v[version]ausgibt. - Eine reguläre (nicht finale) Klasse
Featuremit einer EigenschaftString nameund einer Eigenschaftbool enabled, einem Konstruktor für beide Werte und einer Methodestatus(), die[name]: [enabled ? 'ON' : 'OFF']ausgibt. - Eine Klasse
ExperimentalFeature, dieFeatureerweitert und eine EigenschaftString warninghinzufügt. Überschreibestatus()mit@override, rufe zuerst die Version der übergeordneten Klasse mitsuper.status()auf und gib anschließendWarning: [warning]aus.
- Eine
main.dart: Importiere deine Konfigurationsdatei und veranschauliche den Unterschied zwischen finalen und regulären Klassen:- Erstelle eine
AppConfigmit dem appName'MyApp'und der version'2.0.1', und rufe anschließenddisplay()auf. - Gib eine leere Zeile aus.
- Erstelle eine
Featuremit dem Namen'Dark Mode'und dem Werttruefür enabled, und rufe anschließendstatus()auf. - Gib eine leere Zeile aus.
- Erstelle eine
ExperimentalFeaturemit dem Namen'AI Assistant', dem Wertfalsefür enabled und der Warnung'May be unstable', und rufe anschließendstatus()auf.
- Erstelle eine
Beachte, dass AppConfig als final gekennzeichnet ist, weil ihr Konfigurationsverhalten konsistent und sicher bleiben sollte – keine Unterklasse sollte verändern können, wie Einstellungen verwaltet werden. Feature bleibt dagegen für Erweiterungen offen, sodass ExperimentalFeature spezielles Verhalten hinzufügen kann.
Erwartete Ausgabe:
MyApp v2.0.1
Dark Mode: ON
AI Assistant: OFF
Warning: May be unstableProbier es selbst
import 'config.dart';
void main() {
// TODO: Erstelle eine AppConfig mit appName 'MyApp' und version '2.0.1'
// Rufe dann display() auf
// TODO: Gib eine Leerzeile aus
// TODO: Erstelle ein Feature mit name 'Dark Mode' und enabled true
// Rufe dann status() auf
// TODO: Gib eine Leerzeile aus
// TODO: Erstelle ein ExperimentalFeature mit name 'AI Assistant',
// enabled false und warning 'May be unstable'
// Rufe dann status() auf
}
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