Birden Fazla Struct Gömme
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 37 / 107.
Go, birden fazla yapıyı tek bir yapı içine yerleştirmenize ve farklı kaynaklardaki davranışları birleştirmenize olanak tanır. Bu, diğer dillerdeki çoklu kalıtıma benzer, ancak Go’nun bileşim yaklaşımını kullanır.
type Logger struct{}
func (l Logger) Log(msg string) string {
return "LOG: " + msg
}
type Notifier struct{}
func (n Notifier) Notify(msg string) string {
return "NOTIFY: " + msg
}
type Service struct {
Name string
Logger
Notifier
}
Service yapısı artık her iki gömülü türdeki yöntemlere erişebiliyor:
func main() {
s := Service{Name: "OrderService"}
fmt.Println(s.Log("started")) // LOG: başladı
fmt.Println(s.Notify("new order")) // NOTIFY: yeni sipariş
}
Birden fazla struct gömerken, iki gömülü türün aynı ada sahip yöntemleri varsa adlandırma çakışması meydana gelebilir. Go bu belirsizliği otomatik olarak çözmez:
type A struct{}
func (A) Greet() string { return "Hello from A" }
type B struct{}
func (B) Greet() string { return "Hello from B" }
type Combined struct {
A
B
}
func main() {
c := Combined{}
// c.Greet() - derleme hatası: belirsiz seçici
fmt.Println(c.A.Greet()) // Hello from A
fmt.Println(c.B.Greet()) // Hello from B
}
Çakışmalar ortaya çıktığında, tür adını niteleyici olarak kullanarak hangi gömülü türün yöntemini çağırmak istediğinizi açıkça belirtmelisiniz.
Görev
KolayStruct gömme yoluyla birden fazla özelliği birleştiren bir akıllı ev cihazı sistemi oluşturalım. Ayrı denetleyici türlerini gömerek hem aydınlatmayı kontrol edebilen hem de müzik çalabilen bir cihaz oluşturacaksın.
Kodunu üç dosya arasında düzenleyeceksin:
controllers.go: Farklı özellikler sağlayan iki bağımsız denetleyici struct'ı oluştur:- Bir
LightController;Brightnessalanına (int) veLightControllerdeğerini döndürenSetLight(level int) stringmetoduna sahip olmalı - Bir
AudioController;Volumealanına (int) veVolumedeğerini döndürenSetVolume(level int) stringmetoduna sahip olmalı
Status() stringmetoduna sahip olmalı. Bu, çözmen gereken bir adlandırma çakışması oluşturur.LightController.Status()Brightnessdeğerini,AudioController.Status()iseVolumedeğerini döndürmelidir.- Bir
device.go: BirNamealanına sahip ve hemLightControllerhem deAudioControllertürlerini gömen birSmartDevicestruct'ı oluştur. Her iki denetleyicinin durumuyla birlikte cihaz adını döndürenFullStatus() stringadlı bir metot ekle; belirsizliği, gömülü her türünStatus()metodunu açıkça çağırarak çöz.main.go: Cihaz yapılandırmasını girdiden oku, birSmartDeviceoluştur, ışık ve ses düzeylerini ayarlamak için terfi ettirilen metotları kullan, ardından tam durumu görüntüle.
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: Cihaz adı
- 2. satır: Başlangıç parlaklık düzeyi (tamsayı)
- 3. satır: Başlangıç ses düzeyi (tamsayı)
- 4. satır: Ayarlanacak yeni parlaklık düzeyi (tamsayı)
- 5. satır: Ayarlanacak yeni ses düzeyi (tamsayı)
FullStatus() metodun şunu döndürmelidir:
[Name] - [LightController.Status()], [AudioController.Status()]SetLight ve SetVolume çağrılarının sonuçlarını (gömülü türlerden terfi ettirilen metotlardır) yazdır, ardından tam durumu yazdır.
Örneğin, Living Room Hub, 50, 30, 75 ve 60 verildiğinde çıktın şöyle olmalıdır:
Light set to 75%
Volume set to 60%
Living Room Hub - Brightness: 75%, Volume: 60%SetLight ve SetVolume metotlarının metot terfisi yoluyla SmartDevice üzerinde doğrudan erişilebilir olduğuna, ancak her iki gömülü türde de bu metot bulunduğundan Status() metodunun açık niteleme gerektirdiğine dikkat et.
Kendin dene
package main
import (
"fmt"
)
func main() {
// Girişi oku
var name string
fmt.Scanln(&name)
var initialBrightness int
fmt.Scanln(&initialBrightness)
var initialVolume int
fmt.Scanln(&initialVolume)
var newBrightness int
fmt.Scanln(&newBrightness)
var newVolume int
fmt.Scanln(&newVolume)
// TODO: Verilen ad ve başlangıç değerleriyle bir SmartDevice oluştur
// TODO: Yükseltilmiş SetLight metodunu kullan ve sonucu yazdır
// TODO: Yükseltilmiş SetVolume metodunu kullan ve sonucu yazdır
// TODO: FullStatus() metodunu kullanarak tam durumu yazdır
}
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 PoolKendi başına pratik yap: Online Go derleyicisi