How to do simple inheritance in Go

I'm a Python developer trying to learn Go. I'm currently trying to refactor my first small project, but I'm not too sure how to use the method between structs.

Long story short, how would you do something like this Python code in Go?

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


source to share


3 answers


TL; DR

Go methods not only magically inherit subclasses like other languages ​​like Python or Java. You can define interfaces and use inlining, but you have to implement the methods required for each type. Of course, you can just call the inline method from an external method, however, be careful that any changes happen to the internal object and not the external one.

From the docs:

There's an important way in which nesting differs from subclassing. When we insert a type, methods of that type become methods of the outer type, but when they are called, the method receiver is the inner one, not the outer one. In our example, when Read

method is a bufio.ReadWriter

, it has exactly the same effect as the forwarding method above; the receiver is the field of the reader ReadWriter

, not itself ReadWriter

.

Additional Information

Here are some links from the docs:

http://golang.org/doc/faq#Is_Go_an_object-oriented_language

Is object an object-oriented language?

Yes and no. While Go has types and methods and allows an object-oriented style of programming, there is no type hierarchy. the concept of "interface" in Go provides a different approach that we think is easier to use and in some ways more general. They are also ways of embedding types in other types in order to provide something similar, but not identical to the subclass.



So, you can have interfaces that define what a type should implement, but you have to implement those methods for each type.

You have one addition:

http://golang.org/doc/effective_go.html#embedding

Go does not provide the typical notion of type-driven subclassing, but it does have the ability to "borrow" parts of the implementation by embedding types within a structure or interface.

Interface nesting is very easy. We've mentioned io.Reader

and io.Writer

interfaces before; here are their definitions.

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
} 

      

The io package also exports several other interfaces that indicate objects that can implement several of these methods. For example, there io.ReadWriter

, an interface containing both Read

and Write

. We can specify io.ReadWriter

by specifying two methods explicitly, but it's easier and more memorable to implement two interfaces to form a new one, like this:

// ReadWriter is the interface that combines the Reader and Writer interfaces.
type ReadWriter interface {
    Reader
    Writer
}

      

+7


source


Note: A recent article (today, Nov 18, 2014) titled " Subclassing in Go " illustrates some techniques for simulating "oo" behavior, languages ​​such as java or python in go.

While composition is the norm, if you need the type " Parent

" to resolve a method call at runtime , you need a type Parent

to reference the interface.

Note that this does not provide "true" inheritance, though (as I explained in "Function-Behind Loading in GO Using Interfaces").

See
Inheriting Semantics in Go for details .

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

      

So, you can "subclass" the parent type with the child type (insert the parent and reference it to self

):



type Child struct {
    Parent
}
func (c *Child) flush() {
    c.Parent.flush()
    fmt.Println("child flush")
}

      

This means that if you create an instance of Child and put that instance in "self":

x := new(Child)
x.self = x

      

Then the call x.close()

will print:

parent flush
child flush
close

      

+2


source


Based on two comments on my question, I came up with the following solution in Go:

Go to the playing field: 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.")
}

      

+1


source







All Articles