Menyematkan Beberapa Struct
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 37 dari 107.
Go memungkinkan kamu menyematkan beberapa struct di dalam satu struct, sehingga menggabungkan perilaku dari berbagai sumber. Ini mirip dengan pewarisan berganda di bahasa lain, tetapi menggunakan pendekatan komposisi Go.
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
}
struct Service kini dapat mengakses method dari kedua tipe yang disematkan:
func main() {
s := Service{Name: "OrderService"}
fmt.Println(s.Log("started")) // LOG: dimulai
fmt.Println(s.Notify("new order")) // NOTIFY: pesanan baru
}
Saat menyematkan beberapa struct, konflik penamaan dapat terjadi jika dua tipe yang disematkan memiliki method dengan nama yang sama. Go tidak otomatis mengatasi ambiguitas ini:
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() - error saat compile: selektor ambigu
fmt.Println(c.A.Greet()) // Hello from A
fmt.Println(c.B.Greet()) // Hello from B
}
Saat terjadi konflik, kamu harus secara eksplisit menentukan method dari tipe tersemat yang ingin kamu panggil dengan menggunakan nama tipe sebagai kualifikasi.
Tantangan
MudahMari buat sistem perangkat rumah pintar yang menggabungkan berbagai kemampuan melalui penyematan struct. Kamu akan membuat perangkat yang dapat mengontrol pencahayaan sekaligus memutar musik dengan menyematkan tipe controller yang terpisah.
Kamu akan mengatur kodemu dalam tiga file:
controllers.go: Buat dua struct controller independen yang menyediakan kemampuan berbeda:LightControllerdengan fieldBrightness(int) dan methodSetLight(level int) stringyang mengembalikanLight set to [level]%AudioControllerdengan fieldVolume(int) dan methodSetVolume(level int) stringyang mengembalikanVolume set to [level]%
Status() string. Ini menimbulkan konflik nama yang perlu kamu tangani.LightController.Status()harus mengembalikanBrightness: [Brightness]%danAudioController.Status()harus mengembalikanVolume: [Volume]%.device.go: Buat structSmartDevicedengan fieldNameyang menyematkanLightControllerdanAudioController. Tambahkan method bernamaFullStatus() stringyang mengembalikan nama perangkat beserta status kedua controller, dengan mengatasi ambiguitas melalui pemanggilan eksplisit methodStatus()dari setiap tipe yang disematkan.main.go: Baca konfigurasi perangkat dari input, buatSmartDevice, gunakan method yang dipromosikan untuk mengatur tingkat pencahayaan dan volume, lalu tampilkan status lengkap.
Input berikut akan diberikan:
- Baris 1: Nama perangkat
- Baris 2: Tingkat kecerahan awal (bilangan bulat)
- Baris 3: Tingkat volume awal (bilangan bulat)
- Baris 4: Tingkat kecerahan baru yang akan diatur (bilangan bulat)
- Baris 5: Tingkat volume baru yang akan diatur (bilangan bulat)
Method FullStatus() harus mengembalikan:
[Name] - [LightController.Status()], [AudioController.Status()]Cetak hasil pemanggilan SetLight dan SetVolume (yang dipromosikan dari tipe yang disematkan), lalu cetak status lengkapnya.
Contohnya, jika diberikan Living Room Hub, 50, 30, 75, dan 60, output-mu seharusnya:
Light set to 75%
Volume set to 60%
Living Room Hub - Brightness: 75%, Volume: 60%Perhatikan bahwa SetLight dan SetVolume dapat diakses langsung pada SmartDevice melalui promosi method, tetapi Status() memerlukan kualifikasi eksplisit karena kedua tipe yang disematkan memiliki method tersebut.
Coba sendiri
package main
import (
"fmt"
)
func main() {
// Baca input
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: Buat SmartDevice dengan nama dan nilai awal yang diberikan
// TODO: Gunakan method SetLight yang dipromosikan dan cetak hasilnya
// TODO: Gunakan method SetVolume yang dipromosikan dan cetak hasilnya
// TODO: Cetak status lengkap menggunakan method FullStatus()
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP di Go
File EksternalWorkspace Go dan modulePaket dan ImporNama yang Diekspor dan Tidak DieksporPengantar OOP di Gostruct sebagai classMendefinisikan method pada structPointer receiver vs value receiverInisialisasi structFungsi KonstruktorUlasan: Kalkulator Sederhana4Interface
Pengenalan InterfaceImplementasi ImplisitInterface sebagai KontrakInterface Kosong (any)Type AssertionType SwitchKomposisi InterfaceInterface Stringer & ErrorUlasan: Kalkulator Bentuk7Enkapsulasi
Field yang Diekspor vs Tidak DieksporEnkapsulasi Tingkat PackageMethod Getter dan SetterPenyembunyian Informasi di GoRingkasan: Data Siswa10Generics (Go 1.18+)
Pengantar GenericsParameter TipeBatasan TipeStruct GenerikCara Alternatif untuk Method GenerikRingkasan Koleksi Generik2Mendalami Tipe dan Struct
Tipe Dasar dan KompositDefinisi Tipe KustomTag StructStruct AnonimStruct BersarangNilai Nol dan Nilai BawaanRangkuman: Buku Kontak5Komposisi daripada Pewarisan
Mengapa Go Tidak Memiliki PewarisanDasar Penyematan StructPromosi methodMenyematkan Beberapa StructPenyematan vs AgregasiMembayangi method yang DisematkanRangkuman: Hierarki Karyawan8Penanganan Error & OOP
Interface errorTipe Error KustomPembungkusan Error (fmt.Errorf)Error Sentinelerrors.Is() dan errors.As()Panic, Defer, dan RecoverRangkuman: Parser File3Pointer dan Memori
Dasar-Dasar Pointer di GoPointer ke StructPass by Value vs ReferenceFungsi new()Garbage Collection di GoRekap: Pembuat Linked List6Polimorfisme di Go
Polimorfisme melalui InterfaceDuck Typing di GoAturan Pemenuhan InterfaceKoleksi PolimorfikInjeksi DependensiRangkuman: Pemroses Pembayaran9Konkruensi & OOP
Dasar-dasar GoroutineChannel & KomunikasiChannel Ber-buffer vs Tanpa BufferPernyataan selectsync.Mutex & sync.RWMutexsync.WaitGroupDesain Struct yang Aman untuk ThreadRingkasan: Worker PoolLatihan sendiri: Compiler Go online