我想通过@jimt给出的答案展开这里。这个答案是正确的,并在很大程度上帮助了我。但是,这两种方法(别名,嵌入)都存在一些警告,但我遇到了麻烦。
注意:我不确定使用“父母”和“孩子”这两个术语,尽管我不确定这对构图是最好的。基本上,parent是您要在本地修改的类型。Child是尝试实现该修改的新类型。
方法1-类型定义
type child parent
// or
type MyThing imported.Thing
type child struct {
parent
}
// or with import and pointer
type MyThing struct {
*imported.Thing
}
- 提供对字段的访问。
- 提供对方法的访问。
- 需要考虑初始化。
摘要
- 使用composition方法,如果嵌入式父对象是指针,则不会对其进行初始化。父项必须单独初始化。
- 如果嵌入的父对象是一个指针,并且在初始化子对象时未初始化,则将发生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的接口(及其重新考虑面向对象的方法),然后我遇到了这个问题。