我是一名Python开发人员,正在努力学习Go。目前我正在尝试重构我的第一个小项目,但我不太确定如何在结构之间共享方法。
长话短说,你会如何在Go中使用这个Python代码?
class Super(object):
def CommonMethod(self):
print 'I am the common method.'
class One(Super):
def MethodOne(self):
self.CommonMethod()
print 'I am method one.'
class Two(Super):
def MethodTwo(self):
self.CommonMethod()
print 'I am method two.'
one = One()
one.MethodOne()
two = Two()
two.MethodTwo()
答案 0 :(得分:7)
<强> TL; DR 强>
在Go中,方法不像在Python或Java等其他语言中那样神奇地继承子类。您可以定义接口并使用嵌入,但是您必须实现每种类型所需的方法。当然你可以从外部方法调用嵌入的方法,但是要小心内部对象而不是外部对象会发生任何更改。
来自文档:
嵌入与子类化不同的重要方式。 当我们嵌入一个类型时,那种类型的方法成为了方法 外部类型,但是当它们被调用时,方法的接收者是 内在的类型,而不是外在的类型。在我们的示例中,当
Read
调用bufio.ReadWriter
的方法,它具有完全相同的方法 作为上述转发方法的效果;接收器是ReadWriter
的读者字段,而不是ReadWriter
本身。
更多信息
以下是文档中的一些参考资料:
http://golang.org/doc/faq#Is_Go_an_object-oriented_language
Go是一种面向对象的语言吗?
是和否。虽然Go有类型和方法,但允许使用 面向对象的编程风格,没有类型层次结构。该 Go中“interface”的概念提供了一种与我们不同的方法 相信易于使用,在某些方面更通用。还有 将类型嵌入其他类型以提供类似的东西的方法 - 但是 与子类化不完全相同。
因此,您可以使用接口来定义应在类型中实现的内容,但是您必须为每种类型实现这些方法。
您拥有的一个便利是嵌入:
http://golang.org/doc/effective_go.html#embedding
Go没有提供典型的,类型驱动的子类化概念, 但它确实有能力“借用”一些实现 通过在结构或接口中嵌入类型。
界面嵌入非常简单。我们已经提到
io.Reader
和。{io.Writer
接口之前;这是他们的定义。
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
io包还会导出其他几个指定的接口 可以实现几个这样的方法的对象。例如,那里 是
io.ReadWriter
,包含Read
和Write
的界面。我们 可以通过明确列出两个方法来指定io.ReadWriter
,但是 嵌入两个接口以形成网络更容易,更令人回味 新的,像这样:
// ReadWriter is the interface that combines the Reader and Writer interfaces.
type ReadWriter interface {
Reader
Writer
}
答案 1 :(得分:2)
注意:最近(今天是2014年11月18日)的文章称为&#34; Subclassing in Go&#34;这里介绍了一些模仿go或java等“oo”语言行为的技巧。
虽然构图是常态,但如果你需要&#34; Parent
&#34;用于解析对运行时方法的调用的类型,您需要使用Parent
类型来引用接口。
请注意,这并未提供&#34; true&#34;虽然继承(正如我在&#34; Function Over Loading in GO using interfaces&#34;中解释的那样) 有关详情,请参阅&#34; Inheritance Semantics in Go&#34;。
type Person interface {
close() // define an interface to lookup methods on
flush()
}
type Parent struct {
self Person // retain reference to self for dynamic dispatch
}
func (p *Parent) flush() {
fmt.Println("parent flush")
}
func (p *Parent) close() {
p.self.flush() // call the flush method of whatever the child is.
fmt.Println("close")
}
这样,你可以&#34;子类&#34;具有子类型的父级(嵌入父级及其self
接口引用):
type Child struct {
Parent
}
func (c *Child) flush() {
c.Parent.flush()
fmt.Println("child flush")
}
这意味着如果您创建一个子实例并且将该实例放入&#34; self&#34;:
x := new(Child)
x.self = x
然后打印到x.close()
的电话会打印出来:
parent flush
child flush
close
答案 2 :(得分:1)
根据twotwotwo对我的问题的评论,我在Go上提出了以下解决方案:
去游乐场链接:http://play.golang.org/p/JtPAON93PO
type Super struct{}
type One struct {
Super *Super
}
type Two struct {
Super *Super
}
func (s *Super) CommonMethod() {
fmt.Println("I am the common method.")
}
func (o *One) MethodOne() {
o.Super.CommonMethod()
fmt.Println("I am method one.")
}
func (t *Two) MethodTwo() {
t.Super.CommonMethod()
fmt.Println("I am method two.")
}