首页 > 解决方案 > go 如何强制多态性使用子方法?

问题描述

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

问候

标签: gopolymorphism

解决方案


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的类型的字段的语法糖:A

type A struct {}

type B struct {
    A A
}

主要区别在于,当使用结构嵌入时,您可以A直接在B对象上调用方法b.fun1()。调用 thisa时,传递给的类似 this 的参数fun1不是整个B对象,而只是其中的A字段(就像您调用了一样b.A.fun1()),这就是为什么fun1调用时fun2,它正在调用A实现,因为它没有访问权限到B它存储在里面的对象。


推荐阅读