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 the receiver in Golang can't work like this in C++, in which when dynamic binding is enabled, the code can work like what I want.
I also post another piece of code, which works, but it's too hard to implement, and more like a hack way, I think it's not a Golang style.
So my problem is: if the parent's Bar() method has some logic, for example, open a file, then read some lines, and use Foo() to output these lines to stdout
, and the Child (in the example is B) wants to use most of them, the only difference is that the Child wants Foo() to output the lines to another file. How should I implement it? I have heard that Golang's inheritance can't work like C++ or Java, and what's right way in Golang?
package main import ( "fmt" ) type A struct { } func (a *A) Foo() { fmt.Println("A.Foo()") } func (a *A) Bar() { a.Foo() } type B struct { A } func (b *B) Foo() { fmt.Println("B.Foo()") } func main() { b := B{A: A{}} b.Bar() } output: A.Foo()
the following piece works, but when write
a := A{} a.Bar()
you will encounter a compiler error
package main import ( "fmt" ) type I interface { Foo() } type A struct { i I } func (a *A) Foo() { fmt.Println("A.Foo()") } func (a *A) Bar() { a.i.Foo() } type B struct { A } func (b *B) Foo() { fmt.Println("B.Foo()") } func main() { b := B{A: A{}} b.i = &b // here i works like an attribute of b b.Bar() output: B.Foo()
Overridden methods are not inherited.
Yes yes, I know, Golang has no "overriding, polymorphism etc.", you know, what I mean, just composition. @wellsantos After a few months of writing golang code I agree. I know consider Go to have a very good balance between abstraction concepts and speed of invocation due to binding all methods at compilation time.
You cannot override a non-virtual or static method. The overridden base method must be virtual , abstract , or override . An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.
Invoking overridden method from sub-class : We can call parent class method in overriding method using super keyword. Overriding and constructor : We can not override constructor as parent and child class can never have constructor with same name(Constructor name must always be same as Class name).
As you wrote, what Go has is not really inheritance, the method that allows inheritance like features is called Embedding.
http://golang.org/doc/effective_go.html#embedding
What it means basically is that the embedded struct has no idea that it is embedded, so you cannot override anything that is called from it. You can actually take the embedded struct and take a reference for it only from the embedding struct.
So your best way to do it is more or less like your second example - through some sort of dependency injection using interfaces. i.e - A has a reference to some interface that does the actual work, say worker
, that writes to a file or whatever. Then when instantiating B, you also replace A's worker
with another worker (you can do it even without embedding A of course). The A just does something like myWorker.Work()
without caring what worker it is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With