Polimorfisme melalui Interface
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 41 dari 107.
Polimorfisme memungkinkan berbagai tipe diperlakukan secara seragam melalui interface bersama. Di Go, hal ini sepenuhnya dicapai melalui interface, tanpa pewarisan atau hierarki class.
Saat sebuah fungsi menerima tipe interface sebagai parameter, tipe konkret apa pun yang mengimplementasikan interface tersebut dapat diteruskan. Fungsi itu tidak perlu mengetahui tipe spesifiknya. Fungsi itu hanya memedulikan perilaku yang ditentukan oleh interface:
type Speaker interface {
Speak() string
}
type Dog struct{ Name string }
func (d Dog) Speak() string { return "Woof!" }
type Cat struct{ Name string }
func (c Cat) Speak() string { return "Meow!" }
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
Sekarang MakeSound berfungsi dengan tipe apa pun yang memiliki method Speak():
func main() {
dog := Dog{Name: "Rex"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Guk!
MakeSound(cat) // Meong!
}
Pemanggilan fungsi yang sama menghasilkan perilaku berbeda, bergantung pada tipe sebenarnya yang diteruskan. Inilah polimorfisme dalam praktik. Fungsi MakeSound ditulis sekali, tetapi bekerja dengan jumlah tipe yang tidak terbatas, selama tipe tersebut memenuhi interface Speaker.
Pendekatan ini membuat kodemu fleksibel dan mudah dikembangkan. Untuk menambahkan tipe baru yang dapat berbicara, kamu tidak perlu mengubah fungsi yang sudah ada. Cukup implementasikan interface, lalu semuanya akan bekerja secara otomatis.
Tantangan
MudahMari buat sistem deskripsi kendaraan yang menunjukkan polimorfisme secara langsung. Kamu akan membuat berbagai jenis kendaraan yang semuanya memiliki perilaku umum melalui sebuah interface, lalu menulis satu fungsi yang dapat digunakan dengan kendaraan apa pun.
Kamu akan menyusun kodemu dalam dua file:
vehicles.go: Definisikan interfaceDescriberyang mewajibkan adanya methodDescribe() string. Lalu buat tiga jenis kendaraan yang masing-masing mengimplementasikan interface ini dengan caranya sendiri:Cardengan fieldBranddanModel.Describe()-nya mengembalikanCar: [Brand] [Model]Motorcycledengan fieldBranddanEngineCC(int).Describe()-nya mengembalikanMotorcycle: [Brand] [EngineCC]ccBicycledengan fieldType(seperti "Mountain" atau "Road").Describe()-nya mengembalikanBicycle: [Type]
main.go: Buat fungsi bernamaPrintDescriptionyang menerimaDescriberapa pun dan mencetak hasil pemanggilanDescribe(). Baca detail kendaraan dari input, buat satu kendaraan untuk setiap jenis, lalu berikan masing-masing kePrintDescriptionuntuk menunjukkan bahwa fungsi yang sama dapat digunakan dengan ketiga jenis yang berbeda.
Input berikut akan diberikan:
- Baris 1: Merek mobil
- Baris 2: Model mobil
- Baris 3: Merek sepeda motor
- Baris 4: Kapasitas mesin sepeda motor dalam CC (bilangan bulat)
- Baris 5: Jenis sepeda
Misalnya, jika diberikan Toyota, Camry, Honda, 600, dan Mountain, output-mu seharusnya:
Car: Toyota Camry
Motorcycle: Honda 600cc
Bicycle: MountainPerhatikan bahwa PrintDescription tidak perlu mengetahui apakah yang diterimanya adalah Car, Motorcycle, atau Bicycle. Fungsi ini cukup memanggil Describe(), lalu setiap jenis kendaraan memberikan output uniknya sendiri. Inilah polimorfisme: satu fungsi, banyak perilaku.
Coba sendiri
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
// TODO: Buat fungsi bernama PrintDescription yang menerima Describer apa pun
// dan mencetak hasil pemanggilan Describe()
func main() {
reader := bufio.NewReader(os.Stdin)
// Baca detail mobil
carBrand, _ := reader.ReadString('\n')
carBrand = strings.TrimSpace(carBrand)
carModel, _ := reader.ReadString('\n')
carModel = strings.TrimSpace(carModel)
// Baca detail sepeda motor
motoBrand, _ := reader.ReadString('\n')
motoBrand = strings.TrimSpace(motoBrand)
motoEngineStr, _ := reader.ReadString('\n')
motoEngineStr = strings.TrimSpace(motoEngineStr)
motoEngine, _ := strconv.Atoi(motoEngineStr)
// Baca detail sepeda
bicycleType, _ := reader.ReadString('\n')
bicycleType = strings.TrimSpace(bicycleType)
// TODO: Buat Car, Motorcycle, dan Bicycle menggunakan nilai input
// TODO: Panggil PrintDescription untuk setiap kendaraan guna menunjukkan polimorfisme
fmt.Println("TODO: Print vehicle descriptions")
}
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