Go doesn't support inheritance. But we can achieve similar effects using composition.
The example follows a pattern that is typical in many object-oriented programming languages. A more canonical Go way of implementing this is using strictly composition.
Consider do this.
-
We determine some key characteristics and behaviors that define what a Pet does. While the details differ from one species to another all pets have these behaviors in common: breathe and eat. And we can declare interfaces
Breather
andEater
respectively to presents those behaviors.type Breather interface { Breathe() } type Eater interface { Eat() }
And Go recommends that one-method interfaces be named by the method name + "er" suffix. See interface name in the official Effective Go write-up.
-
We define concrete structs that implement those interfaces.
type SkinBreather struct {} func (sb SkinBreather) Breathe { fmt.Println("breathe through skin") } type LungBreather struct {} func (lb LungBreather) Breathe { fmt.Println("breathe through lung") } type Herbivore struct {} func (h Herbivore) Eat { fmt.Println("eat plants") } type Carnivore struct {} func (c Carnivore) Eat { fmt.Println("eat animals") }
-
Finally define the pet structs.
// Instead of thinking Frog IS a skin breather and a herbivore. Think Forg HAS // skin breathing and plant eating capabilities. type Frog type { SkinBreather Herbivore } type Dog type { LungBreather Carnivore } type Turtle type { LungBreather Herbivore }