是否可以从 Golang 中的父结构调用重写方法?
技术问答
466 人阅读
|
0 人回复
|
2023-09-11
|
我想实现这样的代码,其中B继承A,只覆盖A的Foo()方法,希望代码打印B.Foo(),但还是打印A.Foo(),接收器似乎在Golang 在 C 不能这样工作,代码可以像我想要的那样工作。
" w, B6 ^1 _/ e6 @- [我还发布了另一个代码,可以使用,但太难实现,更像是hack我不这么认为Golang的风格。
) L2 I1 i+ T" Y" r7 ?所以我的问题是:如果父亲 Bar() 方法有一些逻辑,比如打开文件,读取一些行,使用 Foo() 将这些行输出到stdout,而 Child(实例为 B)唯一的区别是 Child 希望 Foo() 将行输出到另一个文件中。我该怎么办?Golang继承不能像C 或Java那样工作,请问Golang正确的方法是什么?
7 T- A6 D* I+ Npackage 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()
/ y8 z9 q$ M1 e1 H- n: C5 H" I D 以下作品有效,但在写入时- e, S2 H, J K: o& ~) _2 Q
a := A{}a.Bar()
. N$ u- c9 ?7 Q( e6 X- V. L 你会遇到编译错误" ]! p& T; N+ h9 K9 h- G( H+ l
package mainimport "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() `: Y/ D8 ~! a& l4 {
: S. w) t2 r2 K/ F
解决方案:
2 O; I1 d% G0 {: S! x5 [9 Q 就像你写的,Go 所拥有的不是真正的继承,这种允许类似特征继承的方法被称为 Embedding。
4 ]9 u, i& K8 G0 p1 P7 Lhttp://golang.org/doc/effective_go.html#embedding2 |0 B; n9 ?4 C0 w- V
这基本上意味着嵌入式结构不知道它是嵌入式的,所以你不能覆盖它调用的任何东西。您实际上可以使用嵌入式结构,并且只从嵌入式结构中获得参考。7 W) J8 B3 `3 E7 G' N& U$ r- a
所以你最好的方法或多或少就像你的第二个例子 - 注入使用接口的某种依赖性。ie - A 引用了一些实际工作接口,如worker写入文件或任何其他内容。然后在实例中 B ,你也可以 A 替换worker为另一个工人(当然,即使不嵌入 A,也可以这样做)。A 只是做类似的事情,myWorker.Work()不在乎它是什么工人。 |
|
|
|
|
|