ฉันต้องการที่จะขยายตัวในคำตอบที่ได้รับจาก @jimt ที่นี่ คำตอบนั้นถูกต้องและช่วยฉันอย่างมากในการแยกแยะสิ่งนี้ อย่างไรก็ตามมีข้อแม้บางประการสำหรับทั้งสองวิธี (นามแฝงการฝัง) ที่ฉันประสบปัญหา
หมายเหตุ : ฉันใช้คำว่า parent และ child แม้ว่าฉันจะไม่แน่ใจว่าเหมาะที่สุดสำหรับการเรียบเรียง โดยทั่วไปพาเรนต์คือประเภทที่คุณต้องการแก้ไขในเครื่อง Child เป็นประเภทใหม่ที่พยายามใช้การปรับเปลี่ยนดังกล่าว
วิธีที่ 1 - คำจำกัดความประเภท
type child parent
// or
type MyThing imported.Thing
- ให้การเข้าถึงฟิลด์
- ไม่ให้การเข้าถึงวิธีการ
type child struct {
parent
}
// or with import and pointer
type MyThing struct {
*imported.Thing
}
- ให้การเข้าถึงฟิลด์
- ให้การเข้าถึงวิธีการ
- ต้องมีการพิจารณาเพื่อเริ่มต้น
สรุป
- การใช้วิธีการจัดองค์ประกอบพาเรนต์แบบฝังจะไม่เริ่มต้นหากเป็นตัวชี้ ต้องเริ่มต้นพาเรนต์แยกกัน
- หากพาเรนต์ฝังตัวเป็นตัวชี้และไม่ได้เตรียมใช้งานเมื่อลูกถูกเตรียมใช้งานจะเกิดข้อผิดพลาดในการกำหนดค่าตัวชี้ nil
- ทั้งนิยามชนิดและกรณีฝังให้การเข้าถึงฟิลด์ของพาเรนต์
- นิยามประเภทไม่อนุญาตให้เข้าถึงเมธอดของพาเรนต์ แต่การฝังพาเรนต์ทำ
คุณสามารถดูสิ่งนี้ได้ในรหัสต่อไปนี้
ตัวอย่างการทำงานในสนามเด็กเล่น
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”
) สำหรับ C # แต่เมื่อดูในวันนี้ฉันจำอินเทอร์เฟซของ Go ได้ทันที (และวิธีการคิดใหม่ในการวางแนววัตถุ) จากนั้นฉันก็มีคำถามนี้