继承和接口

时间:2017-03-15 06:09:56

标签: go struct types interface

我想表达许多语言拥有的extends行为。

在我的Go Code中,我有一些看起来像这样的结构:

type Base struct {
        // Some fields
}

type BaseExtender struct {
        Base
        // Unique fields
}

type AnotherBaseExtender struct {
        Base
        // Unique fields
}

现在,我想编写一个接受任何Base的函数,因为我只需要它“相似的字段”。

func UseTheBase(b Base) {
        testVal := b.thingICareAbout
}

然而,这不起作用。我已经对interface进行了一些挖掘,并认为我可以做类似的事情:

type Base interface {
        // Some fields
}

除非看起来Go通过方法实现自动推断接口。有没有办法模仿这种行为,所以我可以将任何Base传递给我的函数,而不必在Base结构及其所有扩展器上实现一些nop方法?

谢谢!

2 个答案:

答案 0 :(得分:3)

Base意味着你想要继承Go,Go故意避开继承,不要试图重新创建它。您可以嵌入类型,但将其视为嵌入行为,而不仅仅是数据(因为您可能会尝试使用继承语言)。

您的解决方案是正确的,但需要公共方法,并且根据方法定义了接口。只需将您调用它的接口定义为:

type Doer interface {
DoSomething()
}

...
func doit(d Doer) {
   d.DoSomething()
}

doit并不关心它的参数是什么,只要它有一个DoSomething方法。显然这是一个微不足道的例子,并没有任何意义,但是如果你需要在所有扩展器中覆盖某些内容,请问自己为什么Base存在,如果只是添加一些字段,那可能不是单独类型的原因,只是添加您需要的字段。

尽量避免使用其他语言构建的大量分类法。

答案 1 :(得分:0)

要添加,我使用的常见模式是:

type Base interface {
    SomeFunction() int
}

type SimpleBaseImpl struct {
    // Unique fields
}

func (s SimpleBaseImpl) SomeFunction() int {
    return 0
}

type SomethingMoreComplicated struct {
    SimpleBaseImpl
    // Unique fields
}

然后你可以将SomethingMoreComplicated视为“类型”Base - 但同样重要的是要注意golang对组合的偏好(如此处所示)而不是继承。