是否有可能从golang中的父级结构中调用重写的方法? [英] is it possible to call overridden method from parent struct in golang?

查看:838
本文介绍了是否有可能从golang中的父级结构中调用重写的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现这样的代码,其中B从A继承并且只覆盖A的Foo()方法,并且希望代码能够打印B.Foo(),但它仍然会打印A.Foo(),似乎Golang中的接收器在C ++中无法像这样工作,当启用动态绑定时,代码可以像我想要的那样工作。



我也发布了另一段代码,它很有用,但实现起来太难了,更像是一种黑客方式,我认为这不是Golang风格。所以我的问题是:如果父级的Bar()方法有一些逻辑,例如打开一个文件,然后读一些行,并使用Foo()来输出这些行到标准输出,孩子(在这个例子中是B)想要使用其中的大部分,唯一的区别是孩子希望Foo()将行输出到另一个文件。我应该如何实现它?我听说Golang的继承不能像C ++或Java那样工作,在Golang中什么是正确的方式?

  package main 

导入(
fmt


类型A结构{
}

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()
}

输出:A.Foo()

下面的作品,但写时

  a:= A {} 
a.Bar( )

您将遇到编译器错误

 








$ Foo()
}

类型A结构{
i I

}

func(a * A)Foo(){
fmt.Println(A.Foo())
}

func(a * A)Bar (){
aiFoo()

}

type B struct {
A
}

func(b * B)Foo(){
fmt.Println(B.Foo())
}

func main(){
b:= B {A:A {}}
bi =& b //在这里,我的工作方式类似于b
的属性b.Bar()

输出:B.Foo( )


解决方案

继承,允许像特征一样继承的方法称为嵌入。



http://golang.org/doc/effective_go.html #嵌入



这意味着嵌入式结构不知道它是嵌入式的,所以你不能覆盖任何被它调用的东西。实际上,您可以采用嵌入式结构并仅从嵌入结构获取引用。



因此,最好的方法是或多或少地像第二个示例 - 通过使用接口进行某种依赖注入。即--A引用了一些执行实际工作的接口,比如 worker ,写入文件或其他内容。然后,在实例化B时,您还可以将A的 worker 替换为另一个工作者(当然,即使没有嵌入A,也可以这样做)。 A只是做一些像 myWorker.Work()而不关心它是什么工作者。


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

解决方案

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.

这篇关于是否有可能从golang中的父级结构中调用重写的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆