我来自像C ++这样的语言,其中OOP定义明确,通常使用多态。我是使用Go的新手,正试图从多态调用子方法,但我不知道什么是正确的模式。
我创建了两个结构,如您所见,我定义了2个方法fun1和fun2,其中在基本结构中,我仅覆盖其中的一个,而在父结构中,我对其进行了调用。如果多态性正确,则应调用此子方法,至少在我的示例中,不会发生
代码如下:
package main
import (
"fmt"
)
type A struct {
}
type B struct {
A
}
func (a* A) fun1() {
fmt.Println("I'm in A.fun1()")
a.fun2()
}
func (a* A) fun2() {
fmt.Println("I'm in A.fun2()")
}
func (b* B) fun2() {
fmt.Println("I'm in B.fun2()")
}
func main() {
b := B{}
b.fun1()
}
您可以在这里尝试:https://play.golang.org/p/s7xZun-6Otx
输出为
I'm in A.fun1()
I'm in A.fun2()
我很期待
I'm in A.fun1()
I'm in B.fun2()
我该怎么做?为此,在Go中进行良好设计的正确方法是什么?
致谢
答案 0 :(得分:1)
Go对象通常围绕合成而不是继承构建,因为您使用的模式会使A
结构很难对fun2
所做的任何假设。 go中的多态性是在接口级别完成的。首选方法是将“可覆盖的” fun2
功能引入一个单独的接口类型,该接口类型将传递给fun1
函数或存储在包含fun1
的对象中。没有具体的操作方式,很难给出一个合理的例子,但这就是模式:
package main
import (
"fmt"
)
type fun2er interface {
fun2()
}
type A struct {
B fun2er
}
func (a* A) fun1() {
fmt.Println("I'm in A.fun1()")
a.B.fun2()
}
type B1 struct {}
func (b B1) fun2() {
fmt.Println("I'm in B1.fun2()")
}
type B2 struct {}
func (b B2) fun2() {
fmt.Println("I'm in B2.fun2()")
}
func main() {
a1 := A{B: B1{}}
a2 := A{B: B2{}}
a1.fun1()
a2.fun1()
}
这将打印:
I'm in A.fun1()
I'm in B1.fun2()
I'm in A.fun1()
I'm in B2.fun2()
编辑:
我想为引擎盖下的工作方式添加更多色彩。用A
“扩展” B
类型的方法称为结构嵌入,并且主要是用于在类型为B
的{{1}}中添加名称相同的字段的语法糖作为其类型:
A
主要区别在于,使用结构嵌入时,可以直接在type A struct {}
type B struct {
A A
}
对象A
上调用B
方法。调用此参数时,传递给b.fun1()
的类似a
参数不是整个fun1
对象,而只是其中的B
字段(好像您调用了A
),这就是为什么当b.A.fun1()
调用fun1
时,它正在调用fun2
实现,因为它无法访问A
对象存储在里面。