Implementasi Implisit
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 26 dari 107.
Dalam banyak bahasa berorientasi objek seperti Java atau C#, kamu harus menyatakan secara eksplisit bahwa suatu tipe mengimplementasikan interface dengan menggunakan kata kunci seperti implements. Go menggunakan pendekatan yang berbeda: implementasi interface bersifat implisit.
Sebuah tipe memenuhi sebuah interface cukup dengan menerapkan semua method-nya. Kamu tidak perlu mendeklarasikan hubungan tersebut di mana pun. Compiler mengetahuinya secara otomatis.
type Writer interface {
Write(data string) int
}
type FileWriter struct {
Filename string
}
// FileWriter secara implisit mengimplementasikan Writer
func (f FileWriter) Write(data string) int {
fmt.Println("Writing to", f.Filename)
return len(data)
}
Perhatikan bahwa tidak ada deklarasi implements Writer pada FileWriter. Karena FileWriter memiliki method Write(data string) int yang cocok dengan tanda tangan interface, FileWriter otomatis memenuhi interface Writer.
Desain ini memiliki konsekuensi yang kuat: kamu dapat mendefinisikan interface setelah tipe sudah ada. Jika library pihak ketiga memiliki tipe dengan method yang kamu butuhkan, kamu dapat membuat interface yang sudah dipenuhi oleh tipe tersebut tanpa mengubah kode aslinya.
func Save(w Writer, content string) {
w.Write(content)
}
func main() {
fw := FileWriter{Filename: "data.txt"}
Save(fw, "Hello!") // Berfungsi karena FileWriter memenuhi antarmuka Writer
}
Implementasi implisit membuat kode Go tetap tidak bergantung dan fleksibel. Tipe tidak perlu mengetahui interface sebelumnya, sehingga sistem lebih mudah disusun dari bagian-bagian yang independen.
Tantangan
MudahMari buat sistem pengiriman pesan yang menunjukkan cara tipe secara implisit memenuhi interface di Go. Kamu akan membuat berbagai tipe messenger yang semuanya memenuhi interface yang sama, tanpa pernah menyatakan hubungan itu secara eksplisit.
Kamu akan mengatur kodemu dalam dua file:
messengers.go: Definisikan interfaceMessengerdengan satu methodSend(message string) string. Lalu buat dua struct yang secara implisit memenuhi interface ini:EmailMessengerdengan fieldAddress(string)SMSMessengerdengan fieldPhoneNumber(string)
Sendyang mengembalikan string berisi deskripsi pengiriman. Kedua struct tidak boleh secara eksplisit menyatakan bahwa keduanya mengimplementasikanMessenger: Go akan mengetahuinya secara otomatis berdasarkan signature method.main.go: Buat fungsi bernamaDeliverMessageyang menerima sembarangMessengerdan sebuah string pesan, lalu mengembalikan hasil pemanggilanSend. Baca informasi kontak dari input, buat kedua tipe messenger, lalu gunakan fungsimu untuk mengirim pesan melalui masing-masing tipe.
Input berikut akan diberikan:
- Baris 1: Alamat email
- Baris 2: Nomor telepon
- Baris 3: Pesan yang akan dikirim
Method Send-mu harus mengembalikan string dengan format berikut:
- EmailMessenger:
Email to [Address]: [message] - SMSMessenger:
SMS to [PhoneNumber]: [message]
Misalnya, dengan input alice@example.com, 555-1234, dan Hello!, output-mu seharusnya:
Email to alice@example.com: Hello!
SMS to 555-1234: Hello!Inti pentingnya adalah fungsi DeliverMessage-mu menerima sembarang Messenger, dan EmailMessenger serta SMSMessenger sama-sama memenuhi interface tersebut hanya dengan memiliki method Send yang cocok. Tidak ada kata kunci implements di mana pun: implementasi implisit Go menangani semuanya.
Coba sendiri
package main
import (
"bufio"
"fmt"
"os"
)
// TODO: Buat fungsi DeliverMessage yang menerima Messenger apa pun
// dan string pesan, lalu mengembalikan hasil pemanggilan Send
func main() {
reader := bufio.NewReader(os.Stdin)
// Baca alamat email
email, _ := reader.ReadString('\n')
email = email[:len(email)-1]
// Baca nomor telepon
phone, _ := reader.ReadString('\n')
phone = phone[:len(phone)-1]
// Baca pesan
message, _ := reader.ReadString('\n')
if len(message) > 0 && message[len(message)-1] == '\n' {
message = message[:len(message)-1]
}
// TODO: Buat EmailMessenger dengan alamat email
// TODO: Buat SMSMessenger dengan nomor telepon
// TODO: Gunakan DeliverMessage untuk mengirim pesan melalui setiap messenger
// dan cetak hasilnya
}
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