Published on

Polymorphism in Go

Authors

As described in a previous post Go does not have objects the way Java or C# do. Instead Go has structs which you then attach methods to.

There is a type of OO in Go as it has the concepts of interfaces for example:

type PingerClient interface {
    ping() (string, error)
}

The way Go works with interfaces is a struct conforms to an interface if it implements all methods in it:

type PersonClient struct {
    name string,
    surname string
}
...
func (pc PersonClient) ping (string, error) {
    // code to do the ping over here
}

I do not explicitly say PersonClient is implementing the PingerClient interface but as it implements all methods in that interface, Go identifies it as implementing that interface. Also note that:

  • The struct and the interface can live in totally different classes.
  • The struct implementation of the interface has to happen in the same class as the struct.

Go also allows structs and interfaces to compose but not extend one another. Given these details about the language it was a real head scratcher for me initially to work out how I could use polymorphism if at all with Go? After doing some research I discovered that Go handles polymorphism of structs based on the behaviour of structs. What this means in a nutshell is you can use polymorphism in Go if:

  • You make objects implement the same interface.
  • You then make the method take the interface as the parameter.
  • You can pass any structs that implement the same interface as inputs to the method.

So say I have another client called JobService that also implements the PingerClient interface I can then have a method that takes either of JobService or/and PersonClient as inputs:

func pingIt(pc PingerClient) (string, error) {
       return pc.ping()
}

...
jobSvcMsg, possibleError := pingIt(jobService)

personClientMsg, possibleError2 := pingIt(personClient)