我正在尝试在GO中达到这种多态性

type Discoverer interface {
    Discover() string
}

type A struct {
}

func (obj A) GetTest() string {
    return "im in A"
}

type B struct {
    A
}

func (obj B) GetTest() string {
    return "im in B"
}

func (obj A) Discover() string {
    return obj.GetTest()
}

func main() {
    a := A{}
    b := B{}

    fmt.Println(a.Discover())
    fmt.Println(b.Discover())
}

现在我得到输出
im in A
im in A

所以,我的问题是:可以在输出中看到
im in A
im in B

没有B的“替代”发现?
func (obj B) Discover() string {
    return obj.GetTest()
}

为什么?我在struct(作为类)中有很多小方法,并且对所有结构都发现相同的东西,所以我想避免在每个struct(类)中复制并粘贴Discover。

去操场https://play.golang.org/p/nYc2hc3UbG

提前致谢!

最佳答案

否。您正在将A嵌入B中。 B没有为Discover定义,因此始终调用A的版本。该方法的接收器类型为A,而A不知道B或它嵌入在B中。因此A只能调用自己的GetTest()版本。
B满足发现接口(interface)的唯一原因是因为它嵌入了A。它间接实现它。如果要在B上使用该功能,则必须在B上对其进行定义。这根本不是多态,而是组成。 B不是AB具有A。如果需要多态性,则可以使用接口(interface)并实现它们。 B是可发现的,但这仅是因为它具有A

我认为这仅是示例,但实际上您根本没有理由使用Discovery方法。您的界面应该只需要GetTest即可。不要将嵌入与继承混淆。 Go中没有继承。如果您想要多态行为,则可以通过实现接口(interface)来实现它,并且您不能像这样偷工减料,因为嵌入式类型和嵌入者之间的关系不是继承之一,因此没有基类或“替代”。

关于class - GO接口(interface)中的多态性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37259575/

10-14 10:54