Posts Inheritance in Go
Post
Cancel

Inheritance in Go

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main

import "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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package main

import "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

This post is licensed under CC BY 4.0 by the author.