Kütüphane Düzeyinde Gizlilik
Coddy'nin Dart Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 32 / 110.
Dart'ta gizlilik, sınıf düzeyinde değil, kitaplık düzeyinde uygulanır. Bu, Java veya C++ gibi dillerden önemli bir farktır. Dart'ta bir kitaplık genellikle tek bir dosyadır veya part yönergeleriyle bağlanan birden fazla dosyadır.
Gizli üyeler (_ ile başlayanlar), aynı kütüphane içindeki her yerden, hatta diğer sınıflardan bile erişilebilirdir:
// Her iki sınıf da aynı dosyada (aynı kütüphane)
class Engine {
int _horsepower = 200; // Bu kütüphaneye özel
}
class Car {
void showPower(Engine engine) {
print(engine._horsepower); // Erişilebilir! Aynı kütüphane
}
}Ancak, bir sınıfı farklı bir dosyadan içe aktardığınızda, özel (private) üyeleri gerçekten gizli hale gelir:
// dosya: engine.dart
class Engine {
int _horsepower = 200;
int get power => _horsepower;
}
// dosya: main.dart
import 'engine.dart';
void main() {
var engine = Engine();
// print(engine._horsepower); // Hata! Erişilemez
print(engine.power); // Çalışır - genel (public) getter kullanılıyor
}Bu kütüphane düzeyindeki gizlilik, aynı dosyadaki sınıfların uygulama detaylarını harici koddan gizlerken birbirleriyle yakından iş birliği yapabileceği anlamına gelir. Bu, ilgili sınıfların aynı kütüphane içinde bir arada düzenlenmesini teşvik eden bilinçli bir tasarım tercihidir.
Görev
KolayDart'da kütüphane düzeyindeki gizliliğin (library-level privacy) nasıl çalıştığını gösteren bir ekip işbirliği sistemi kuralım. Aynı dosyadaki sınıfların birbirlerinin özel (private) üyelerine nasıl erişebildiğini, ancak ayrı dosyalardaki kodların buna erişemediğini göreceksiniz.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
team.dart: Bu dosya, aynı kütüphane içinde birlikte çalışan iki sınıf içerecektir:- Genel (public) bir
String nameve50değerine ayarlanmış özel (private) birint _performanceScoreiçeren birMembersınıfı. İsmi alan bir yapıcı (constructor) ve özel puanı döndüren genel bir alıcı (getter) olanperformanceScoreekleyin. - Aynı dosyada bulunan ve
Membersınıfının özel alanına doğrudan erişebilen (çünkü aynı kütüphanededirler) birTeamLeadsınıfı. Bu sınıfın genel birString namedeğişkeni, ismi alan bir yapıcısı vemember._performanceScorealanına doğrudan erişen, ona10ekleyen ve[leadName] boosted [memberName]'s score to [newScore]yazdıran birevaluateMember(Member member)metodu olmalıdır.
- Genel (public) bir
main.dart: Ekip dosyanızı içe aktarın (import) ve erişim farkını gösterin:'Alice'adında birMemberoluşturun'Bob'adında birTeamLeadoluşturun- Alice üzerindeki genel alıcıyı kullanarak
Initial score: [score]yazdırın - Bob'un
evaluateMemberkullanarak Alice'i değerlendirmesini sağlayın - Genel alıcıyı kullanarak
Updated score: [score]yazdırın Direct access from main: Not allowedyazdırın (bu bizemain.dartdosyasının farklı bir kütüphanede olduğu için_performanceScorealanına doğrudan erişemeyeceğini hatırlatır)
Buradaki temel nokta, TeamLead sınıfının Member sınıfının özel _performanceScore alanını doğrudan okuyabilmesi ve değiştirebilmesidir; çünkü her iki sınıf da aynı dosyada (aynı kütüphanede) bulunur. Ancak, main.dart içindeki kod, farklı bir kütüphanede olduğu için genel alıcıyı (getter) kullanmak zorundadır.
Beklenen çıktı:
Initial score: 50
Bob boosted Alice's score to 60
Updated score: 60
Direct access from main: Not allowedKopya kağıdı
Dart'ta gizlilik, sınıf düzeyinde değil, kütüphane düzeyinde uygulanır. Bir kütüphane genellikle tek bir dosyadır veya part direktifleriyle bağlanan birden fazla dosyadır.
Gizli üyeler bir alt çizgi (_) ile başlar ve aynı kütüphane içindeki her yerden, hatta diğer sınıflardan bile erişilebilirdir:
// Her iki sınıf da aynı dosyada (aynı kütüphane)
class Engine {
int _horsepower = 200; // Bu kütüphaneye özel
}
class Car {
void showPower(Engine engine) {
print(engine._horsepower); // Erişilebilir! Aynı kütüphane
}
}Bir sınıfı farklı bir dosyadan içe aktardığınızda, gizli üyeleri gizli hale gelir:
// dosya: engine.dart
class Engine {
int _horsepower = 200;
int get power => _horsepower;
}
// dosya: main.dart
import 'engine.dart';
void main() {
var engine = Engine();
// print(engine._horsepower); // Hata! Erişilemez
print(engine.power); // Çalışır - genel (public) getter kullanılıyor
}Bu tasarım, ilgili sınıfların aynı kütüphane içinde bir arada düzenlenmesini teşvik ederek, uygulama detaylarını dış koddan gizlerken birbirleriyle yakın iş birliği yapmalarına olanak tanır.
Kendin dene
import 'team.dart';
void main() {
// YAPILACAK: 'Alice' adında bir Member oluşturun
// YAPILACAK: 'Bob' adında bir TeamLead oluşturun
// YAPILACAK: Alice üzerindeki genel (public) getter'ı kullanarak "Initial score: [score]" yazdırın
// YAPILACAK: evaluateMember kullanarak Bob'un Alice'i değerlendirmesini sağlayın
// YAPILACAK: Genel (public) getter'ı kullanarak "Updated score: [score]" yazdırın
// YAPILACAK: "Direct access from main: Not allowed" yazdırın
// Not: Burada alice._performanceScore'a erişemeyiz çünkü
// main.dart, team.dart'tan farklı bir kütüphanededir
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarKütüphaneler ve ImportlarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarÖrnek DeğişkenleriConstructor TemelleriÖzet - Basit Hesap Makinesi4Null Safety
Null Safety'ye GirişNullable ve Non-Nullable? ve ! OperatörleriLate Anahtar Kelimesi ve Null SafetyNull-Aware OperatörleriSınıflarda Null SafetyÖzet - Kullanıcı Profili Sistemi7Soyut Sınıflar ve Arayüzler
Soyut SınıflarSoyut MetotlarDart'ta ArayüzlerÖrtük ArayüzlerUygulama vs. GenişletmeÇoklu ArayüzlerÖzet - Şekil Hesaplayıcı10Koleksiyonlar ve Generic'ler
List, Set, Map Genel BakışTip Güvenli KoleksiyonlarGeneric SınıflarGeneric MetotlarGeneric KısıtlamalarIterable ve IteratorÖzet - Generic Depolama2Dart'ta Yapıcılar
Varsayılan Yapıcıİsimlendirilmiş Yapıcılarİlklendirme ListeleriSabit YapıcılarFabrika YapıcılarıYönlendiren YapıcılarÖzet - Şekil Oluşturucu5Kapsülleme
Public ve Private Üyeler_ Öneki KuralıKütüphane Düzeyinde GizlilikGetter ve Setter DetaylarıBilgi GizlemeÖzet - Öğrenci Kayıtları8Mixin'ler
Mixin'lere GirişMixin OluşturmaBirden Fazla Mixin KullanımıMixin'lerde on Anahtar KelimesiMixin vs KalıtımMixin vs ArayüzÖzet - Hayvan Sistemi11Özel Metotlar
toString() OverridehashCode ve == OverrideComparable Arayüzücall() MetodunoSuchMethod OverrideÖzet - Özel Koleksiyon14Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı17Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakter SistemiAraç Kiralama Servisi3Sınıf Özellikleri
Instance ve Statik ÜyelerFinal ve Const AlanlarLate DeğişkenlerStatik Metotlar ve AlanlarGetters ve SettersÖzet - Banka Hesabı Yöneticisi6Kalıtım
Temel Kalıtımsuper Anahtar KelimesiMetot Ezme@override Anotasyonufinal Sınıf Anahtar KelimesiYapıcı Metotlar ve KalıtımÖzet - Çalışan Hiyerarşisi9Çok Biçimlilik
Çok Biçimlilik TemelleriInterface'ler ile Çok BiçimlilikÇalışma Zamanı Tip Kontrolüis ve as OperatörleriCovariant Anahtar KelimesiÖzet - Ödeme İşlemcisi12Asenkron OOP
Futures ve async/awaitStream TemelleriStream Controller'larAsenkron KurucularSınıf Metotlarında Asenkron KullanımıÖzet - Data Fetcher15Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı