Promosi method
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 36 dari 107.
Sama seperti penyematan struct mempromosikan field ke struct luar, Go juga mempromosikan method dari tipe yang disematkan. Artinya, kamu dapat memanggil method yang didefinisikan pada struct yang disematkan secara langsung pada struct luar.
type Engine struct {
Horsepower int
}
func (e Engine) Start() string {
return "Engine started"
}
type Car struct {
Model string
Engine // disematkan
}
Karena Car menyematkan Engine, method Start() otomatis dipromosikan:
func main() {
c := Car{
Model: "Sedan",
Engine: Engine{Horsepower: 200},
}
fmt.Println(c.Start()) // Engine berhasil dinyalakan
fmt.Println(c.Engine.Start()) // ini juga berfungsi
}
Promosi ini memiliki konsekuensi penting bagi interface. Jika tipe yang disematkan memenuhi sebuah interface, tipe luar juga otomatis memenuhinya:
type Starter interface {
Start() string
}
func Ignite(s Starter) {
fmt.Println(s.Start())
}
func main() {
c := Car{Model: "Sedan", Engine: Engine{Horsepower: 200}}
Ignite(c) // Car memenuhi Starter melalui Engine
}
Tipe Car tidak pernah secara eksplisit mengimplementasikan Starter, tetapi tetap memenuhi interface tersebut karena Engine yang disematkan di dalamnya memiliki method yang diwajibkan. Inilah cara Go menggunakan kembali perilaku tanpa pewarisan tradisional.
Tantangan
MudahMari kita buat sistem pemutar musik yang menunjukkan bagaimana method dari tipe yang disematkan dipromosikan ke tipe luarnya, dan bagaimana hal ini memungkinkan pemenuhan interface melalui komposisi.
Kamu akan menyusun kodemu dalam dua file:
audio.go: Buat komponen dasar untuk pemutar musikmu:- Struct
AudioPlayerdengan fieldBrandbertipe string dan methodPlay() stringyang mengembalikan[Brand] playing audio - Interface
Playableyang mensyaratkan methodPlay() string - Struct
Smartphonedengan fieldModelyang menyematkanAudioPlayer - Struct
Tabletdengan fieldModelyang menyematkanAudioPlayer
- Struct
main.go: Buat fungsi bernamaStartPlaybackyang menerima nilai apa pun bertipePlayabledan mengembalikan hasil pemanggilanPlay(). Baca informasi perangkat dari input, buat Smartphone dan Tablet, lalu tunjukkan bahwa keduanya memenuhi interfacePlayablemelaluiAudioPlayeryang disematkan, meskipun kedua tipe itu tidak secara eksplisit mengimplementasikanPlay().
Input berikut akan diberikan:
- Baris 1: Nama model Smartphone
- Baris 2: Merek audio Smartphone
- Baris 3: Nama model Tablet
- Baris 4: Merek audio Tablet
Untuk setiap perangkat, cetak modelnya, lalu hasil dari meneruskannya ke StartPlayback.
Misalnya, dengan input iPhone 15, Apple Audio, iPad Pro, dan Beats, outputmu seharusnya:
iPhone 15
Apple Audio playing audio
iPad Pro
Beats playing audioPerhatikan bahwa Smartphone dan Tablet dapat diteruskan ke StartPlayback karena method Play() dari AudioPlayer otomatis dipromosikan ke setiap tipe luar, sehingga memenuhi interface Playable tanpa kode tambahan.
Coba sendiri
package main
import (
"bufio"
"fmt"
"os"
)
// TODO: Buat fungsi StartPlayback yang menerima Playable apa pun
// dan mengembalikan hasil pemanggilan Play()
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Baca model smartphone
scanner.Scan()
smartphoneModel := scanner.Text()
// Baca merek audio smartphone
scanner.Scan()
smartphoneBrand := scanner.Text()
// Baca model tablet
scanner.Scan()
tabletModel := scanner.Text()
// Baca merek audio tablet
scanner.Scan()
tabletBrand := scanner.Text()
// TODO: Buat Smartphone dengan AudioPlayer yang disematkan
// TODO: Buat Tablet dengan AudioPlayer yang disematkan
// TODO: Cetak model smartphone, lalu panggil StartPlayback dengan smartphone tersebut
// TODO: Cetak model tablet, lalu panggil StartPlayback dengan tablet tersebut
_ = smartphoneModel
_ = smartphoneBrand
_ = tabletModel
_ = tabletBrand
fmt.Println("TODO: Complete the implementation")
}
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