为了账号安全,请及时绑定邮箱和手机立即绑定

GO 接口中的多态性

GO 接口中的多态性

Go
杨__羊羊 2022-01-10 16:46:41
我正在尝试在 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 Aim in A所以,我的问题是:有可能在输出中看到im in Aim in B没有 B 的“覆盖”发现?func (obj B) Discover() string {    return obj.GetTest()}为什么?我在结构(作为类)中有很多小方法,并且发现对于所有结构都几乎相同,所以我想避免在每个结构(类)中复制和粘贴 Discover去游乐场https://play.golang.org/p/nYc2hc3UbG提前致谢!
查看完整描述

2 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

不,你要嵌入ABB没有定义Discover,因此A总是调用on 版本。该方法有一个类型的接收器,A并且AB知道它嵌入在B. 因此A只能称其为自己的版本GetTest()

B满足发现接口的唯一原因是它已A嵌入。它间接地实现它。如果你想打开功能B,你必须定义它B。这根本不是多态性,而是组合。B不是ABA。如果你想要多态,你可以使用接口并实现它们。B是一个可发现的,但只是因为它有一个A.

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


查看完整回答
反对 回复 2022-01-10
?
神不在的星期二

TA贡献1963条经验 获得超6个赞

为了补充@evanmcdonnal 的观点,嵌入既不是继承也不是多态。继承恰好是一种方便,您可以免费获得接口的实现,但在 Go 中,它是显式的。正如@evanmcdonnal 所指出的,嵌入可能看起来像继承,但并非如此。


相反,您应该将概念多态性与继承以及嵌入和继承分开。大多数面向对象的语言都没有进行比较。例如,下面将是多态性的实现。请注意,Discover需要一个接口,A并B实现了接口,使得函数本身多态性。


package main


import "fmt"


type A struct{}

type B struct{}


type Test interface{

    GetTest() string

}


func (a *A) GetTest() string {

    return "i am in A"

}


func (b *B) GetTest() string {

    return "i am in B"

}


func Discover(t Test) string {

    return t.GetTest()

}


func main() {

    a := &A{}

    b := &B{}


    fmt.Println(Discover(a))

    fmt.Println(Discover(b))

}


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 263 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号