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.
- Implied inheritance using interfaces with Polymorphism
- 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