I want to implement such code, where B inherit from A and only override A\'s Foo() method, and I hope the code to print B.Foo(), but it still print A.Foo(), it seems that th
Been struggling with this myself. Found 2 solutions:
Idiomatic Go way: implement the common "method" as external function with interface as argument.
package main
import "fmt"
// Fooer has to Foo
type Fooer interface {
Foo()
}
// Bar is a proxy, that calls Foo of specific instance.
func Bar(a Fooer) {
a.Foo()
}
//////////////////////////////////////////////////////////////////////
// usage
func main() {
b := &B{} // note it is a pointer
// also there's no need to specify values for default-initialized fields.
Bar(b) // prints: B.Foo()
}
//////////////////////////////////////////////////////////////////////
// implementation
// A is a "base class"
type A struct {
}
func (a *A) Foo() {
fmt.Println("A.Foo()")
}
// B overrides methods of A
type B struct {
A
}
func (b *B) Foo() {
fmt.Println("B.Foo()")
}
Try it on Go Playground: https://play.golang.org/p/2TbmHUs9_Dt
Similar to your second option: interface hackery. However, since Bar() is not specific to A (it is common to A and B), let's move it to base class, and hide implementation details and all dangerous stuff:
package main
import "fmt"
//////////////////////////////////////////////////////////////////////
// Usage
func main() {
b := NewB()
b.Bar() // prints: B.Foo()
a := NewA()
a.Bar() // prints: A.Foo()
}
//////////////////////////////////////////////////////////////////////
// Implementation.
// aBase is common "ancestor" for A and B.
type aBase struct {
ABCD // embed the interface. As it is just a pointer, it has to be initialized!
}
// Bar is common to A and B.
func (a *aBase) Bar() {
a.Foo() // aBase has no method Foo defined, so it calls Foo method of embedded interface.
}
// a class, not exported
type a struct {
aBase
}
func (a *a) Foo() {
fmt.Println("A.Foo()")
}
// b class, not exported
type b struct {
aBase
}
func (b *b) Foo() {
fmt.Println("B.Foo()")
}
//////////////////////////////////////////////////////////////////////
// Now, public functions and methods.
// ABCD describes all exported methods of A and B.
type ABCD interface {
Foo()
Bar()
}
// NewA returns new struct a
func NewA() ABCD {
a := &a{}
a.ABCD = a
return a
}
// NewB returns new struct b
func NewB() ABCD {
b := &b{}
b.ABCD = b
return b
}
Try it on Go Playground: https://play.golang.org/p/0Zcs_arturP