如何使这个Go抽象类型工作?

时间:2015-04-10 20:14:03

标签: go

package main

import "fmt"

type IA interface {
    A()
    B()
}

type AbsA struct {
    IA
}

type CA struct {
    AbsA
}

func (a CA) B() {
    fmt.Println("Show B")
}

func (a AbsA) A() {
    fmt.Println("Show A")
    a.B()
}

func t7() {
    var a IA
    a = CA{}
    a.A()
}

func main() {
    t7()
}

运行此命令会出现nil指针恐慌,因为当AbsA调用B()时,它将使用嵌入式IA,但IA是一个接口。

有没有办法让这项工作?

修改

我尝试制作一个抽象的超类,AbsA只实现了接口的一部分,但它需要使用其他函数,A是AbsA的子类,只实现接口的其余部分。

但这看起来很糟糕,有没有其他方法可以做到这一点?实际上,我只是想做这样的事情

func (a IA)A(){
    fmt.Println("Show A")
    a.B()
}

但是不能将接口用作接收器。

2 个答案:

答案 0 :(得分:3)

我不知道你要完成什么,但是如果你用嵌入式接口定义结构,你需要初始化它们。

http://play.golang.org/p/C32yWfNDRp

var a IA
a = CA{
    AbsA: AbsA{
        IA: CA{},
    },
}
a.A()

如果您期望OOP继承行为,Go不提供。嵌入只是自动委托的一种形式。

答案 1 :(得分:1)

不,至少不像你在这里设计的那样。我并不完全确定你要完成的是什么,但这是非常糟糕的嵌入使用。它不起作用的原因是因为CA类型依赖于方法AbsA的嵌入式A()类型,然后调用方法b'但B()的唯一实际实现是将CA作为接收类型,因此一旦您调用A()的嵌入式类型实现,它就无法回调嵌入类型实现B()

你将嵌入视为一条双向的街道,但实际上嵌入类型知道它嵌入的所有方法,并且嵌入对嵌入器一无所知。在我个人看来,这应该会产生编译器错误。也许在将来的版本中它会(如果我在编译时可以告诉您编译器应该能够100%的时间获得运行时错误,对吧?)。

现在您需要使用B()类型的接收器实现Absa,或者使用A()类型的接收器添加CA的另一个实现。我不确定你要完成什么,所以我无法说出最佳的行动方案。请注意,如果我将此与传统的OOP继承相关联,我会将您的代码描述为尝试从父类中访问子类的属性,显然它是不可能的。 Absa永远无法调用为嵌入它的类型定义的B()实现。就像尝试使用从父类继承类型定义的方法一样,只有在大多数OOP语言中才会工作或有意义,否则会出现编译时错误。