如何在Go中进行简单继承

时间:2014-11-18 01:42:51

标签: python inheritance go

我是一名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()

3 个答案:

答案 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,包含ReadWrite的界面。我们   可以通过明确列出两个方法来指定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;。

Example (play.golang.org)

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