我正在尝试在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
不是A
,B
具有A
。如果需要多态性,则可以使用接口(interface)并实现它们。 B
是可发现的,但这仅是因为它具有A
。
我认为这仅是示例,但实际上您根本没有理由使用Discovery
方法。您的界面应该只需要GetTest
即可。不要将嵌入与继承混淆。 Go中没有继承。如果您想要多态行为,则可以通过实现接口(interface)来实现它,并且您不能像这样偷工减料,因为嵌入式类型和嵌入者之间的关系不是继承之一,因此没有基类或“替代”。
关于class - GO接口(interface)中的多态性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37259575/