Pola final i const
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 18 z 110.
Podczas deklarowania pól w klasie możesz użyć final lub const, aby określić, czy wartości mogą się zmieniać po inicjalizacji. Oba słowa tworzą niezmienne wartości, ale działają inaczej.
Pole final można ustawić tylko raz, ale jego wartość jest określana w czasie wykonywania programu. Możesz przypisać mu wartość w deklaracji lub za pomocą konstruktora:
class Person {
final String name;
final DateTime createdAt = DateTime.now();
Person(this.name);
}
Person p = Person('Alice');
// p.name = 'Bob'; // Błąd: nie można ponownie przypisać wartości do pola finalname jest ustawiane podczas tworzenia obiektu, a createdAt przechowuje bieżący czas. Obie wartości są niezmienne po inicjalizacji.
Pole static const musi mieć wartość znaną w czasie kompilacji. Należy do samej klasy i jest współdzielone przez wszystkie jej instancje:
class Circle {
static const double pi = 3.14159;
final double radius;
Circle(this.radius);
double get area => Circle.pi * radius * radius;
}Kluczowa różnica: pola final mogą przechowywać wartości obliczane w czasie działania programu (takie jak DateTime.now()), natomiast const wymaga stałych znanych w czasie kompilacji. Pola instancji nie mogą być bezpośrednio const — na poziomie klasy dozwolone jest tylko static const.
Wyzwanie
ŁatwyZbudujmy system katalogu produktów, który pokazuje różnicę między polami final i static const. Utworzysz produkty z niezmiennymi właściwościami i współdzielonymi wartościami konfiguracyjnymi.
Podzielisz kod na dwa pliki:
product.dart: Zdefiniuj klasęProduct, która reprezentuje produkt w sklepie. Klasa powinna zawierać:static const double taxRateustawione na0.08(8% podatku wspólnego dla wszystkich produktów)static const String currencyustawione na'USD'final String namedla nazwy produktu (ustawianej przez konstruktor)final double basePricedla ceny bazowej produktu (ustawianej przez konstruktor)final String sku(jednostka magazynowa), która łączy prefiks z nazwą produktu i jest obliczana na liście inicjalizacyjnej jako'SKU-', po którym następuje nazwa zapisana wielkimi literami- Konstruktor przyjmujący
nameibasePrice - Getter
priceWithTax, który oblicza cenę z podatkiem - Metodę
display(), która wyświetla informacje o produkcie
main.dart: Zaimportuj klasę produktu i utwórz dwa produkty:'Laptop'z ceną bazową999.99'Mouse'z ceną bazową29.99
display()dla każdego produktu w podanej kolejności.
Metoda display() powinna wyświetlać tekst w dokładnie takim formacie:
[sku] - [name]: [basePrice] [currency] (with tax: [priceWithTax] [currency])Podczas wyświetlania zaokrąglij priceWithTax do 2 miejsc po przecinku za pomocą toStringAsFixed(2).
Oczekiwany wynik:
SKU-LAPTOP - Laptop: 999.99 USD (with tax: 1079.99 USD)
SKU-MOUSE - Mouse: 29.99 USD (with tax: 32.39 USD)Spróbuj swoich sił
import 'product.dart';
void main() {
// TODO: Utwórz obiekt Product o nazwie 'Laptop' z ceną bazową 999.99
// TODO: Utwórz obiekt Product o nazwie 'Mouse' z ceną bazową 29.99
// TODO: Wywołaj display() dla każdego produktu po kolei (najpierw Laptop, potem Mouse)
}
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