Membayangi method yang Disematkan
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 39 dari 107.
Terkadang, kamu perlu membuat struct luar menyediakan implementasinya sendiri untuk method yang sudah dimiliki oleh tipe yang disematkan. Ini disebut shadowing, dan memungkinkanmu mengganti method yang dipromosikan dengan perilaku khusus.
Saat kamu mendefinisikan method pada struct luar dengan nama yang sama seperti method yang disematkan, method luar diutamakan:
type Animal struct {
Name string
}
func (a Animal) Speak() string {
return "Some sound"
}
type Dog struct {
Animal
Breed string
}
func (d Dog) Speak() string {
return "Woof!"
}
Sekarang saat kamu memanggil Speak() pada Dog, method luarnya digunakan:
func main() {
d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Labrador"}
fmt.Println(d.Speak()) // Woof! , method milik Dog
fmt.Println(d.Animal.Speak()) // Some sound, method milik Animal
}
method yang disematkan tidak hilang. Kamu tetap bisa mengaksesnya secara eksplisit melalui nama tipe yang disematkan. Pola ini berguna saat kamu ingin menyesuaikan perilaku sambil tetap menyediakan implementasi aslinya, misalnya untuk memanggilnya dari dalam method yang kamu timpa:
func (d Dog) Speak() string {
return d.Animal.Speak() + " (but actually Woof!)"
}
Shadowing memberimu kendali atas perilaku mana yang ditampilkan, sambil tetap memberi akses ke perilaku asli melalui kualifikasi eksplisit.
Tantangan
MudahMari buat sistem notifikasi yang memungkinkan berbagai channel notifikasi menyesuaikan cara mereka memformat dan mengirim pesan. Kamu akan menggunakan method shadowing agar channel tertentu dapat mengganti perilaku default, sekaligus tetap dapat mengakses implementasi aslinya saat diperlukan.
Kamu akan mengatur kodemu dalam tiga file:
base.go: Buat structBaseNotificationdengan fieldTitledanPriority(keduanya bertipe string). Berikan methodFormat() stringyang mengembalikan notifikasi dalam format standar:[Priority] Title.channels.go: Buat dua tipe channel notifikasi yang menyematkanBaseNotificationdan melakukan shadowing pada methodFormatdengan implementasi masing-masing:EmailNotificationdengan fieldRecipient.Format()harus mengembalikanEmail to [Recipient]: [Priority] TitleSlackNotificationdengan fieldChannel.Format()harus memanggil methodBaseNotification.Format()yang disematkan dan menambahkan#[Channel]:di awal hasilnya
main.go: Baca detail notifikasi dari input, buat kedua tipe notifikasi, lalu tunjukkan shadowing dengan mencetak:- Output berformat dari
EmailNotification(menggunakan method-nya yang melakukan shadowing) - Format dasar
EmailNotification(dengan memanggil method yang disematkan secara eksplisit) - Output berformat dari
SlackNotification(yang secara internal menggunakan method dasar)
- Output berformat dari
Input berikut akan diberikan:
- Baris 1: Judul notifikasi
- Baris 2: Tingkat prioritas
- Baris 3: Penerima email
- Baris 4: Nama channel Slack
Contohnya, jika diberikan Server Alert, HIGH, admin@company.com, dan ops-alerts, outputmu seharusnya:
Email to admin@company.com: HIGH Server Alert
[HIGH] Server Alert
#ops-alerts: [HIGH] Server AlertPerhatikan bagaimana EmailNotification sepenuhnya menggantikan pemformatan dasar, sedangkan SlackNotification menyempurnakannya dengan memanggil method asli dan menambahkan konteks channel. Kedua pendekatan ini menunjukkan berbagai cara menggunakan method shadowing secara efektif.
Coba sendiri
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Baca judul notifikasi
scanner.Scan()
title := scanner.Text()
// Baca tingkat prioritas
scanner.Scan()
priority := scanner.Text()
// Baca penerima email
scanner.Scan()
recipient := scanner.Text()
// Baca nama channel Slack
scanner.Scan()
channel := scanner.Text()
// TODO: Buat EmailNotification dengan notifikasi dasar, judul, prioritas, dan penerima
// TODO: Buat SlackNotification dengan notifikasi dasar, judul, prioritas, dan channel
// TODO: Cetak output terformat dari EmailNotification (gunakan method miliknya yang menutupi method dasar)
// TODO: Cetak format dasar EmailNotification (panggil method yang disematkan secara eksplisit)
// TODO: Cetak output terformat dari SlackNotification
fmt.Println() // Penampung sementara, hapus saat mengimplementasikan
}
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