Saya ingin memperluas jawaban yang diberikan oleh @jimt di sini . Jawaban itu benar dan sangat membantu saya dalam menyelesaikan masalah ini. Namun, ada beberapa peringatan untuk kedua metode (alias, sematan) yang saya punya masalah.
Catatan : Saya menggunakan istilah orangtua dan anak, meskipun saya tidak yakin itu yang terbaik untuk komposisi. Pada dasarnya, parent adalah tipe yang ingin Anda modifikasi secara lokal. Child adalah tipe baru yang mencoba mengimplementasikan modifikasi itu.
Metode 1 - Jenis Definisi
type child parent
// or
type MyThing imported.Thing
- Memberikan akses ke bidang.
- Tidak menyediakan akses ke metode.
type child struct {
parent
}
// or with import and pointer
type MyThing struct {
*imported.Thing
}
- Memberikan akses ke bidang.
- Memberikan akses ke metode.
- Membutuhkan pertimbangan untuk inisialisasi.
Ringkasan
- Menggunakan metode komposisi, induk yang disematkan tidak akan menginisialisasi jika itu adalah sebuah pointer. Induk harus diinisialisasi secara terpisah.
- Jika orang tua yang disematkan adalah pointer dan tidak diinisialisasi ketika anak diinisialisasi, kesalahan nereferensi pointer akan terjadi.
- Definisi tipe dan case embed menyediakan akses ke bidang induk.
- Definisi tipe tidak memungkinkan akses ke metode induk, tetapi menanamkan induk tidak.
Anda dapat melihat ini dalam kode berikut.
contoh kerja di taman bermain
package main
import (
"fmt"
)
type parent struct {
attr string
}
type childAlias parent
type childObjParent struct {
parent
}
type childPointerParent struct {
*parent
}
func (p *parent) parentDo(s string) { fmt.Println(s) }
func (c *childAlias) childAliasDo(s string) { fmt.Println(s) }
func (c *childObjParent) childObjParentDo(s string) { fmt.Println(s) }
func (c *childPointerParent) childPointerParentDo(s string) { fmt.Println(s) }
func main() {
p := &parent{"pAttr"}
c1 := &childAlias{"cAliasAttr"}
c2 := &childObjParent{}
// When the parent is a pointer it must be initialized.
// Otherwise, we get a nil pointer error when trying to set the attr.
c3 := &childPointerParent{}
c4 := &childPointerParent{&parent{}}
c2.attr = "cObjParentAttr"
// c3.attr = "cPointerParentAttr" // NOGO nil pointer dereference
c4.attr = "cPointerParentAttr"
// CAN do because we inherit parent's fields
fmt.Println(p.attr)
fmt.Println(c1.attr)
fmt.Println(c2.attr)
fmt.Println(c4.attr)
p.parentDo("called parentDo on parent")
c1.childAliasDo("called childAliasDo on ChildAlias")
c2.childObjParentDo("called childObjParentDo on ChildObjParent")
c3.childPointerParentDo("called childPointerParentDo on ChildPointerParent")
c4.childPointerParentDo("called childPointerParentDo on ChildPointerParent")
// CANNOT do because we don't inherit parent's methods
// c1.parentDo("called parentDo on childAlias") // NOGO c1.parentDo undefined
// CAN do because we inherit the parent's methods
c2.parentDo("called parentDo on childObjParent")
c3.parentDo("called parentDo on childPointerParent")
c4.parentDo("called parentDo on childPointerParent")
}
“extension methods are not object-oriented”
) untuk C #, tetapi ketika melihatnya hari ini, saya langsung teringat antarmuka Go (dan pendekatannya untuk memikirkan kembali orientasi objek), dan kemudian saya punya pertanyaan yang sangat mirip ini.