Dışa Aktarılan ve Aktarılmayan Alanlar
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 47 / 107.
Go'da, struct düzeyinde kapsülleme, alan adlarının büyük/küçük harf durumuyla kontrol edilir. Bu basit kural, alanlara struct'ın tanımlandığı paketin dışından erişilip erişilemeyeceğini belirler.
Büyük harf ile başlayan alanlar dışa aktarılır—herhangi bir paketten erişilebilir. Küçük harf ile başlayan alanlar ise dışa aktarılmaz—yalnızca aynı paket içinden erişilebilir:
// "user" paketi içinde
type User struct {
Name string // Dışa aktarılmış - her yerden erişilebilir
Email string // Dışa aktarılmış - her yerden erişilebilir
password string // Dışa aktarılmamış - sadece "user" paketi içinden erişilebilir
age int // Dışa aktarılmamış - sadece "user" paketi içinden erişilebilir
}
Başka bir paket bu struct'ı içe aktarıp kullandığında, yalnızca dışa aktarılan alanlarla etkileşime girebilir:
// "main" paketi içinde
import "user"
func main() {
u := user.User{
Name: "Alice", // çalışır
Email: "a@mail.com", // çalışır
// password: "secret", // derleme hatası: bilinmeyen alan
}
fmt.Println(u.Name) // çalışır
// fmt.Println(u.password) // derleme hatası: dışa aktarılmamış alana başvurulamaz
}
Bu mekanizma hassas verileri ve dahili uygulama ayrıntılarını korur. password alanı paket dışından doğrudan okunamaz veya değiştirilemez, bu da diğer kodları sizin sağladığınız yöntemleri kullanmaya zorlar. Bu, nesne yönelimli programlamada kapsüllemenin (encapsulation) temel bir ilkesi olan veri gizlemeyi gerçekleştirme konusundaki Go yaklaşımıdır.
Görev
KolayDışa aktarılan (exported) ve dışa aktarılmayan (unexported) alanlar aracılığıyla kapsüllemeyi (encapsulation) gösteren bir banka hesabı sistemi kuralım. Güvenli genel bilgileri açığa çıkarırken hassas finansal verileri koruyan bir paket oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
account.go:mainpaketi içinde, gerçek bir banka hesabını uygun veri korumasıyla modelleyen birBankAccountyapısı (struct) oluşturun:HolderName(dışa aktarılan) - hesap sahibinin adı, herkese açık olarak gösterilmesi güvenlidirAccountType(dışa aktarılan) - hesap türü (örneğin, "Savings", "Checking")balance(dışa aktarılmayan) - korunması gereken gerçek bakiyepin(dışa aktarılmayan) - hesap PIN kodu, son derece hassas veri
BankAccountişaretçisi (pointer) döndüren birNewBankAccountyapıcı (constructor) fonksiyonu ekleyin. Ayrıca şu formatı döndüren birGetPublicInfo() stringmetodu ekleyin:Account: [HolderName] ([AccountType])main.go: Girdiden hesap ayrıntılarını okuyun, yapıcıyı kullanarak birBankAccountoluşturun ve kapsüllemeyi gösterin. Metodu kullanarak genel bilgileri yazdırın, ardından dışa aktarılan her bir alana doğrudan erişerek ayrı satırlarda yazdırın. Dışa aktarılmayan alanlar (balancevepin) korunmaktadır; bunları yalnızca yapıcı aracılığıyla ayarlayabilirsiniz.
Aşağıdaki girdiler sağlanacaktır:
- Satır 1: Hesap sahibi adı
- Satır 2: Hesap türü
- Satır 3: Başlangıç bakiyesi (float olarak)
- Satır 4: PIN kodu
Örneğin, Alice Johnson, Savings, 5000.50 ve 1234 verildiğinde, çıktınız şöyle olmalıdır:
Account: Alice Johnson (Savings)
Holder: Alice Johnson
Type: SavingsBakiye ve PIN'in çıktıda asla görünmediğine dikkat edin; bunlar yapının içinde güvenli bir şekilde gizlenmiştir ve yalnızca paket içinden erişilebilirler. Bu, kapsüllemenin işleyişidir: hassas veriler korunurken genel bilgilere erişilebilir kalır.
Kopya kağıdı
Go'da, kapsülleme (encapsulation) struct'lardaki alan adlarının büyük/küçük harf durumuyla kontrol edilir:
- Büyük harfle başlayan alanlar dışa aktarılır (herhangi bir paketten erişilebilir)
- Küçük harfle başlayan alanlar dışa aktarılmaz (yalnızca aynı paket içinden erişilebilir)
type User struct {
Name string // Dışa aktarıldı - her yerden erişilebilir
Email string // Dışa aktarıldı - her yerden erişilebilir
password string // Dışa aktarılmadı - yalnızca aynı paket içinden erişilebilir
age int // Dışa aktarılmadı - yalnızca aynı paket içinden erişilebilir
}
Başka bir paketten bir struct kullanırken, yalnızca dışa aktarılan alanlara erişilebilir:
import "user"
func main() {
u := user.User{
Name: "Alice", // çalışır
Email: "a@mail.com", // çalışır
// password: "secret", // derleme hatası: bilinmeyen alan
}
fmt.Println(u.Name) // çalışır
// fmt.Println(u.password) // derleme hatası: dışa aktarılmamış alana başvurulamaz
}
Bu mekanizma, hassas verileri ve dahili uygulama ayrıntılarını koruyarak harici kodun erişim için sağlanan yöntemleri kullanmasını zorunlu kılar.
Kendin dene
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Hesap sahibinin adını oku
holderName, _ := reader.ReadString('\n')
holderName = strings.TrimSpace(holderName)
// Hesap türünü oku
accountType, _ := reader.ReadString('\n')
accountType = strings.TrimSpace(accountType)
// Başlangıç bakiyesini oku
balanceStr, _ := reader.ReadString('\n')
balanceStr = strings.TrimSpace(balanceStr)
balance, _ := strconv.ParseFloat(balanceStr, 64)
// PIN kodunu oku
pinStr, _ := reader.ReadString('\n')
pin := strings.TrimSpace(pinStr)
// TODO: Yapıcıyı (constructor) kullanarak yeni bir BankAccount oluşturun
// account := NewBankAccount(...)
// TODO: GetPublicInfo() metodunu kullanarak genel bilgileri yazdırın
// TODO: Dışa aktarılan (exported) alana doğrudan erişerek hesap sahibi adını yazdırın
// fmt.Println("Holder:", ...)
// TODO: Dışa aktarılan (exported) alana doğrudan erişerek hesap türünü yazdırın
// fmt.Println("Type:", ...)
// Note: balance ve pin dışa aktarılmamıştır (unexported) - buraya doğrudan erişilemezler
// Bunlar struct içinde güvenli bir şekilde kapsüllenmiştir (encapsulated)
_ = balance // balance değişkenini kullandığınızda bu satırı kaldırın
_ = pin // pin değişkenini kullandığınızda bu satırı kaldırın
}
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
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker Pool