避免在“子类型”之间重复代码

时间:2019-11-07 22:21:34

标签: go interface

我正在将旧的Java项目重写为Go。

我已经在工作中做了一些Go语言,但是我不知道如何将OOP(带有抽象类等)转换为Go语言。

在这个想法中,我有两种类型(很快3)具有相同的方法,但是其他一些类型(最多只有1或2种)应该具有相同的签名,但不具有相同的主体。

我知道Go没有某种继承。现在我有这样的东西:

type A struct {...}
func (a *A) M1 (){ stuff1 }
func (a *A) M2 (){ stuff2 }
func (a *A) SM (){ special stuff A }

然后:

type B struct {...}
func (b *B) M1 (){ stuff1 }
func (b *B) M2 (){ stuff2 }
func (b *B) SM (){ special stuff B }

我不知道Go如何管理这个问题。在Java中,我做了一个抽象类,然后用我的两个具体类实现了它。

我想要的不是不必复制M1()和M2(),而是能够具有泛型类型来调用这些方法,然后只需为这两种类型定义SM()。

2 个答案:

答案 0 :(得分:3)

您可以嵌入结构,例如:

type Common struct {}

func (c *Common) M1() {
    fmt.Println("M1")
}

func (c *Common) M2() {
    fmt.Println("M2")
}

type A struct {
    Common
}

func (a *A) SM() {
    fmt.Println("A SM()")
}

type B struct {
    Common
}

func (b *B) SM() {
    fmt.Println("B SM()")
}   

type Thing interface {
    M1()
    M2()
    SM()
}
func main() {
    var a Thing = &A{}
    var b Thing = &B{}

    a.M1()
    b.M2()
    a.SM()
    b.SM()
}

https://play.golang.org/p/Q3mIH_W8X44

答案 1 :(得分:-1)

有两种不同的解决方法-嵌入并不是唯一的答案。如果这些方法要访问您在伪代码中定义的类型的数据(例如A.M1需要访问A的字段),则嵌入将无济于事,因为嵌入式类型没有了解它所嵌入的类型。您需要从整体上和作为Go程序重新考虑您的设计,而不是像将其设计为Java程序一样设计并尝试使这些概念在Go中工作。正如许多人所发现的那样,尝试在Go中进行OOP设计往往会产生很多挫败感,而成功却很少。

另一方面,如果这些方法不需要不需要访问任何字段,那么为什么要使用这些方法?这些可能只是纯函数,这将使它们更易于使用和推理,并且完全消除了嵌入或伪造继承的任何麻烦。