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

时间:2015-11-18 15:04:57

标签: go

msimsp

我想得到"我是Sub"但是我得到了#34;我超级"代替。

我已经知道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"。

2 个答案:

答案 0 :(得分:7)

嵌入不是子类化。 Go中没有超类或子类。 Sub这里不是Super的“孩子”。它包含Super。你无法做到。您需要以不同的方式组织代码,以便不需要它。

例如,这里(playground)是一种更自然的方式在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)
}

不是专注于类(Go没有),而是专注于接口。这不是是什么的问题,而是他们可以做什么的问题。这是一种非常强大的编程方法,在实践中通常比继承抽象更灵活,更不容易出错。

答案 1 :(得分:2)

将Go中的函数想象为它们都属于单个命名空间。 Go真的没有类,方法或继承,所以你尝试的东西永远不会按你想要的方式工作。

换句话说,当你定义一个这样的函数时:

func (f *Foo) DoStuff()

你可以想象真的被定义为:

func DoStuff(f *Foo)

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

至于如何以Go方式执行此操作,请尝试使用接口:

<强> http://play.golang.org/p/8ELw-9e7Re

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{})
}