dongwang788787 2016-05-16 17:17
浏览 45
已采纳

GO接口中的多态性

I'm trying to reach this way of polymorphism in 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())
}

Now I'm getting in output

im in A
im in A

So, my question is: It is possible to see in output

im in A
im in B

Without "override" Discover of B?

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

Why? I've alot of small methods in struct (as classes) and Discover pretty the same for all structs, so I want to avoid copy&paste Discover in each struct(class)

go playground https://play.golang.org/p/nYc2hc3UbG

Thanks in advance!

  • 写回答

2条回答 默认 最新

  • dongsu3138 2016-05-16 17:30
    关注

    No. You're embedding A in B. B has no definition for Discover, therefor the version on A is always invoked. That method has a receiver of type A and A has no awareness of B or the fact that it's embedded in B. Therefor A can only call it's own version of GetTest().

    The only reason B satisfies the discover interface is because it has A embedded. It implements it indirectly. If you want the functionality on B, you have to define it on B. This isn't polymorphism at all, it's composition. B isn't an A, B has an A. If you want polymorphism, you use interfaces and implement them. B is a discoverable, but only because it has an A.

    I would assume this is just for the example but you actually have no reason at all to even have this Discovery method. Your interface should just require GetTest instead. Don't confuse embedding with inheritance. There is no inheritance in Go. If you want polymorphic behavior you achieve it by implementing interfaces and you can't cut corners like this because the relationship between an embedded type and the embeddor is not one of inheritance, there is no base class or "overrides".

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作