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()
}
但是不能将接口用作接收器。
答案 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语言中才会工作或有意义,否则会出现编译时错误。