Inheritance in Go

Alen Alex
2 min readMar 7, 2022

Since Golang does not support classes, the concept of inheritance is achieved using interfaces and structs.
Then again, structs cannot directly extend from interfaces or other structs.
So, one could argue that Golang does not have inheritance

Inheritance can be achieved in Golang in 3 ways.

  1. Implied inheritance using interfaces with Polymorphism
  2. Inheritance Embedding

Implied inheritance using interfaces with Polymorphism

For people coming from the object oriented world (like me), it can be considered as an alternative of inheritance.
This concept is actually Polymorphism in Golang.

The idea is that, if you have an interface and a struct that has the same structure, then you can consider it akin to a child instance of the interface.

The concept sounds similar to a weakly typed language.
If the struct looks like an interface, then it can be used in place of the interface.
In short, if a struct has all the methods of the interface defined, then its reference can be used in place of the interface.

package mainimport "fmt"type sleeper interface {
Sleep()
}
type Cat struct{}func (c *Cat) Sleep() {
fmt.Println("purrrrrr")
}
type Dog struct{}func (d *Dog) Sleep() {
fmt.Println("brrrrr")
}
func main() {
pets := []sleeper{new(Cat), new(Dog)}
for _, x := range pets {
x.Sleep()
}
var pussyCat1 sleeper
pussyCat1 = new(Cat)
pussyCat1.Sleep()
var tiger sleeper
tiger = &Dog{}
tiger.Sleep()
// This will not work
// var doggy sleeper
// doggy = Dog{}
// doggy.Sleep()
}

Click to try out the above code

Inheritance by Embedding

This is the closest I feel Go works, when it comes to inheritance.
You can consider this like a syntactical sugar to implement inheritance in Go (although it isn’t really the case)

In this method you embed an interface or struct into another interface or struct.

See below:

package mainimport "fmt"type livingBeings interface {
GetLivingBeing() string
}
type species interface {
livingBeings
GetSpecies() string
}
type human struct {
species
Name string
}
type person struct {
human
age int
}
func (p *person) GetSpecies() string {
return "human"
}
func (h *human) GetLivingBeing() string {
return "human being"
}
func main() {
alen := person{
human: human{
Name: "Alen",
},
age: 10,
}
fmt.Println(alen.Name)
fmt.Println(alen.age)
fmt.Println(alen.GetSpecies())
fmt.Println(alen.GetLivingBeing())
}

Click to try out the above code

References

Foot note

As an alternative, you can read this document and more as I write on my personal blog here.

Buy Me A Coffee

--

--