Słowo kluczowe final dla klas
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 40 z 110.
Czasami chcesz uniemożliwić rozszerzanie klasy. Słowo kluczowe final, zastosowane do klasy, uniemożliwia dziedziczenie po niej innym klasom.
final class DatabaseConnection {
String connectionString;
DatabaseConnection(this.connectionString);
void connect() {
print('Connected to $connectionString');
}
}
// To spowodowałoby błąd podczas kompilacji:
// class CustomConnection extends DatabaseConnection { }Oznaczenie klasy jako final jest przydatne, gdy jej rozszerzenie mogłoby naruszyć jej zamierzone działanie lub gwarancje bezpieczeństwa. Na przykład klasa zarządzająca wrażliwymi zasobami może wymagać, aby jej metody nie były nadpisywane w nieoczekiwany sposób.
Dart 3 wprowadził również powiązane modyfikatory: base wymusza użycie extends (a nie implements) przez podklasy, a sealed ogranicza dziedziczenie do tej samej biblioteki. Na razie skup się na final jako najprostszym sposobie całkowitego zablokowania klasy.
Używaj klas final, gdy masz pewność, że projekt klasy jest kompletny, a dziedziczenie tylko powodowałoby problemy. Nie nadużywaj jednak tej możliwości — większość klas zyskuje na tym, że pozostają otwarte na rozszerzenia.
Wyzwanie
ŁatwyZbudujmy bezpieczny system konfiguracji, który pokazuje, kiedy i dlaczego warto uniemożliwić rozszerzanie klasy. Utworzysz klasę finalną, która zarządza ustawieniami aplikacji, zapewniając, że jej zachowania nie będzie można zmienić przez dziedziczenie.
Podzielisz kod na dwa pliki:
config.dart: Zdefiniuj tutaj klasy konfiguracji:- Klasa
final class AppConfig, której nie można rozszerzać. Powinna mieć właściwościString appNameiString version, konstruktor przyjmujący obie wartości oraz metodędisplay(), która wyświetla[appName] v[version] - Zwykła (niefinalna) klasa
Featurez właściwościamiString nameibool enabled, konstruktorem przyjmującym obie wartości oraz metodąstatus(), która wyświetla[name]: [enabled ? 'ON' : 'OFF'] - Klasa
ExperimentalFeature, która rozszerzaFeaturei dodaje właściwośćString warning. Zastąp metodęstatus(), używając@override, aby najpierw wywołać wersję rodzica za pomocąsuper.status(), a następnie wyświetlićWarning: [warning]
- Klasa
main.dart: Zaimportuj plik konfiguracji i pokaż różnicę między klasami finalnymi a zwykłymi:- Utwórz
AppConfigz appName'MyApp'i version'2.0.1', a następnie wywołajdisplay() - Wyświetl pusty wiersz
- Utwórz
Featureo nazwie'Dark Mode'i z enabled ustawionym natrue, a następnie wywołajstatus() - Wyświetl pusty wiersz
- Utwórz
ExperimentalFeatureo nazwie'AI Assistant', z enabled ustawionym nafalsei warning równym'May be unstable', a następnie wywołajstatus()
- Utwórz
Zwróć uwagę, że AppConfig jest oznaczona jako final, ponieważ jej zachowanie związane z konfiguracją powinno pozostać spójne i bezpieczne — żadna podklasa nie powinna móc zmienić sposobu zarządzania ustawieniami. Tymczasem Feature pozostaje otwarta na rozszerzenia, dzięki czemu ExperimentalFeature może dodawać wyspecjalizowane zachowanie.
Oczekiwany wynik:
MyApp v2.0.1
Dark Mode: ON
AI Assistant: OFF
Warning: May be unstableSpróbuj swoich sił
import 'config.dart';
void main() {
// TODO: Utwórz obiekt AppConfig z appName 'MyApp' i version '2.0.1'
// Następnie wywołaj display()
// TODO: Wypisz pustą linię
// TODO: Utwórz obiekt Feature z name 'Dark Mode' i enabled true
// Następnie wywołaj status()
// TODO: Wypisz pustą linię
// TODO: Utwórz obiekt ExperimentalFeature z name 'AI Assistant',
// enabled false i warning 'May be unstable'
// Następnie wywołaj status()
}
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