Prywatność na poziomie biblioteki
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 32 z 110.
W Dart prywatność jest egzekwowana na poziomie biblioteki, a nie klasy. To kluczowa różnica w porównaniu z językami takimi jak Java czy C++. Biblioteka w Dart to zazwyczaj pojedynczy plik lub wiele plików połączonych dyrektywami part.
Prywatne składowe (te, których nazwy zaczynają się od _) są dostępne w dowolnym miejscu w tej samej bibliotece, nawet z innych klas:
// Obie klasy w tym samym pliku (tej samej bibliotece)
class Engine {
int _horsepower = 200; // Prywatne w obrębie tej biblioteki
}
class Car {
void showPower(Engine engine) {
print(engine._horsepower); // Dostępne! Ta sama biblioteka
}
}Jednak gdy zaimportujesz klasę z innego pliku, jej prywatne składowe stają się naprawdę ukryte:
// plik: engine.dart
class Engine {
int _horsepower = 200;
int get power => _horsepower;
}
// plik: main.dart
import 'engine.dart';
void main() {
var engine = Engine();
// print(engine._horsepower); // Błąd! Brak dostępu
print(engine.power); // Działa — używa publicznego gettera
}Ta prywatność na poziomie biblioteki oznacza, że klasy w tym samym pliku mogą ściśle ze sobą współpracować, a jednocześnie ukrywać szczegóły implementacji przed zewnętrznym kodem. To celowy wybór projektowy, który zachęca do organizowania powiązanych klas w tej samej bibliotece.
Wyzwanie
ŁatwyZbudujmy system współpracy zespołowej, który pokazuje, jak działa prywatność na poziomie biblioteki w Dart. Zobaczysz, jak klasy w tym samym pliku mogą uzyskiwać dostęp do swoich prywatnych składowych, podczas gdy kod w osobnych plikach nie może.
Podzielisz kod na dwa pliki:
team.dart: Ten plik będzie zawierał dwie ściśle współpracujące ze sobą klasy w tej samej bibliotece:- Klasa
Memberz publicznymString namei prywatnymint _performanceScorezainicjowanym wartością50. Dodaj konstruktor przyjmujący imię oraz publiczny getterperformanceScore, który zwraca prywatny wynik. - Klasa
TeamLeadw tym samym pliku, która może bezpośrednio uzyskiwać dostęp do prywatnego pola klasyMember(ponieważ znajdują się w tej samej bibliotece). Ta klasa powinna mieć publiczneString name, konstruktor przyjmujący imię oraz metodęevaluateMember(Member member), która bezpośrednio uzyskuje dostęp domember._performanceScore, dodaje do niego10i wyświetla[leadName] boosted [memberName]'s score to [newScore].
- Klasa
main.dart: Zaimportuj plik zespołu i pokaż różnicę w dostępie:- Utwórz obiekt
Membero imieniu'Alice' - Utwórz obiekt
TeamLeado imieniu'Bob' - Wyświetl
Initial score: [score], używając publicznego gettera obiektu Alice - Poleć Bobowi ocenić Alice za pomocą
evaluateMember - Wyświetl
Updated score: [score], używając publicznego gettera - Wyświetl
Direct access from main: Not allowed(przypomina nam to, żemain.dartnie może bezpośrednio uzyskać dostępu do_performanceScore, ponieważ znajduje się w innej bibliotece)
- Utwórz obiekt
Najważniejsza kwestia jest taka, że TeamLead może bezpośrednio odczytywać i modyfikować prywatne _performanceScore klasy Member, ponieważ obie klasy znajdują się w tym samym pliku (tej samej bibliotece). Natomiast kod w main.dart musi używać publicznego gettera, ponieważ znajduje się w innej bibliotece.
Oczekiwany wynik:
Initial score: 50
Bob boosted Alice's score to 60
Updated score: 60
Direct access from main: Not allowedSpróbuj swoich sił
import 'team.dart';
void main() {
// TODO: Utwórz obiekt Member o imieniu 'Alice'
// TODO: Utwórz obiekt TeamLead o imieniu 'Bob'
// TODO: Wypisz "Initial score: [score]", używając publicznego gettera obiektu Alice
// TODO: Niech Bob oceni Alice za pomocą evaluateMember
// TODO: Wypisz "Updated score: [score]", używając publicznego gettera
// TODO: Wypisz "Direct access from main: Not allowed"
// Uwaga: Nie możemy tutaj uzyskać dostępu do alice._performanceScore, ponieważ
// main.dart znajduje się w innej bibliotece niż team.dart
}
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