Go 如何在父方法中调用子方法?

Go 如何在父方法中调用子方法?,go,Go,我想得到“我是替补”,但我得到的是“我是超级” 我已经知道sub.WhoAmI将调用sub.Super.WhoAmI,但我仍然想知道是否有办法获得“我是sub”。在Python中编写以下代码时: package main import "fmt" type Super struct{} func (super *Super) name() string { return "Super" } func (super *Super) WhoAmI() { fmt.Printf

我想得到“我是替补”,但我得到的是“我是超级”

我已经知道sub.WhoAmI将调用sub.Super.WhoAmI,但我仍然想知道是否有办法获得“我是sub”。在Python中编写以下代码时:

package main

import "fmt"

type Super struct{}

func (super *Super) name() string {
    return "Super"
}

func (super *Super) WhoAmI() {
    fmt.Printf("I'm %s.\n", super.name())
}

type Sub struct {
    Super
}

func (sub *Sub) name() string {
    return "Sub"
}

func main() {
    sub := &Sub{Super{}}
    sub.WhoAmI()
}

我可以得到“我是Sub”

嵌入不是子类化。Go中没有超类或子类
Sub
这里不是
Super
的“子项”。它包含一个
Super
。你不能做你想做的事。您需要以不同的方式组织代码,以便不需要它

例如,here()是在Go中执行此操作的更自然的方法:

class Super(object):

    def name(self):
        return "Super"

    def WhoAmI(self):
        print("I'm {name}".format(name=self.name()))

class Sub(Super):

    def name(self):
        return "Sub"


if __name__ == "__main__":
    sub  = Sub()
    sub.WhoAmI()

与其关注类(Go没有),不如关注接口。这不是事情是什么的问题,而是他们能做什么的问题。这是一种非常强大的编程方法,实际上通常比继承抽象灵活得多,也不容易出错。

将Go中的函数想象成它们都属于一个名称空间。Go实际上没有类、方法或继承,因此您所尝试的将永远不会按照您想要的方式工作

换句话说,当您定义这样的函数时:

package main

import "fmt"

type Namer interface {
    Name() string
}

type Super struct{}

func (sub *Super) Name() string {
    return "Super"
}

type Sub struct{}

func (sub *Sub) Name() string {
    return "Sub"
}

func WhoAmI(namer Namer) {
    fmt.Printf("I'm %s.\n", namer.Name())
}

func main() {
    sub := &Sub{}
    WhoAmI(sub)
}
你可以想象它被定义为:

func (f *Foo) DoStuff()
因此,您可能会注意到为什么Go选择在
Super
结构上调用
name
函数,因为它是唯一匹配的函数签名。(请注意,在您的
WhoAmI
函数中
super
被定义为
super*super
,因此Go将其与相同类型的相应函数匹配。)

至于如何做到这一点,请尝试使用接口:

func DoStuff(f *Foo)

使用界面意味着您必须对代码执行多重操作,如
WhoAmI
方法,它在
Sub
Parent
结构中重复显示。我认为传递对象并使用
reflect.ValueOf(&Sub{}).MethodByName(“WhoAmI”).Call(nil)
是一个更好的选择
package main

import "fmt"

type Indentifier interface {
    WhoAmI() string
}

type A struct{}

func (a *A) WhoAmI() string {
    return "A"
}

type B struct{}

func (b *B) WhoAmI() string {
    return "B"
}

func doSomething(x Indentifier) {
    fmt.Println("x is a", x.WhoAmI())
}

func main() {
    doSomething(&A{})
    doSomething(&B{})
}