Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to call overridden method from parent struct in Golang?

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() 
like image 297
zhaozhi Avatar asked Jan 21 '14 06:01

zhaozhi


People also ask

Are overridden methods inherited?

Overridden methods are not inherited.

Does Golang support method overriding?

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.

Can you override an overridden method?

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.

How do you call a base class overridden method?

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).


1 Answers

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.

like image 115
Not_a_Golfer Avatar answered Sep 20 '22 18:09

Not_a_Golfer