如何使用子方法强制多态?

时间:2019-06-21 00:32:00

标签: go polymorphism

我来自像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中进行良好设计的正确方法是什么?

致谢

1 个答案:

答案 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对象存储在里面。