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()
}
Running this will get a nil pointer panic, because when AbsA
calls B()
, it will use the embedded IA
, but IA
is an interface.
Is there any way to make this work?
EDIT
I try to make a abstract super class, AbsA only implement part of interface, but it need to use other functions,A is a subclass of AbsA, only implement the rest part of interface.
But this looks bad, is there any other way to do this ? actually , I just want to do something like this
func (a IA)A(){
fmt.Println("Show A")
a.B()
}
but go can not use a interface as a receiver.
No, at least not as you have it designed here. I'm not entirely sure what you're trying to accomplish but this is a very very poor use of embedding. The reason it doesn't work is because the CA
type relies on the embedded AbsA
type for method A()
which then calls a 'method b' but the only actual implementation of B()
has CA as the receiving type so once you've calling into the embedded types implementation of A()
it can't call back up to the embedding types implementation of B()
.
You're treating embedding as if it's a two way street but in reality the embedding type knows all the methods on it's embed and the embed knows nothing about the embeddor. In my personal opinion, this should generate a compiler error. Perhaps in a future release it will (if I can tell at compile time that you will get a run-time error 100% of the time the compiler should able to too, right?).
As it is now you either need to implement B()
with a receiver of type Absa
or add another implementation of A()
with a receiver of type CA
. I'm not really sure what you're trying to accomplish so I can't say what the best course of action is. Note that if I were relating this to traditional OOP inheritance I would describe your code as attempting to access properties of a child class from within a parent class, clearly it's not possible. Absa
will never be able to call up to an implementation of B()
defined for the type embedding it. Just like trying to use a method defined on an inheriting type from the parent would never work or make sense only in most of the OOP languages you would get a compile time error.
I don't know what you're trying to accomplish, but if you're defining structs with embedded interfaces, you need to initialize them.
http://play.golang.org/p/C32yWfNDRp
var a IA
a = CA{
AbsA: AbsA{
IA: CA{},
},
}
a.A()
If you're expecting OOP inheritance behavior, Go doesn't provide that. Embedding is only a form of automatic delegation.