Search code examples
inheritancegocomposition

How to give access of struct method to an embedded method in Go?


Using inheritance in Python

class Animal(object):
    def eat(self):
        print self.name + " is eating " + self.get_food_type()


class Dog(Animal):
    def __init__(self, name):
        self.name = name

    def get_food_type(self):
        return "dog food"

dog = Dog("Brian")
dog.eat()

# Expected output => "Brian is eating dog food"

UPDATE: In the example above, my sub class is calling a method from its super class and the function in super class is actually aware of the sub class methods. I want to be able to accomplish a similar effect in Go.

The closest I can get with inheritance is struct embedding in Go.

type Animal struct {
    Name string
}

func (a *Animal) Eat() {
    fmt.Println(a.Name + " is eating " + a.GetFoodType())
}

type Dog struct {
    *Animal
}

func (d *Dog) GetFoodType() string {
    return "dog food"
}

func main() {
    dog := &Dog{&Animal{"Brian"}}
    dog.Eat()
}

# Error => type *Animal has no field or method GetFoodType

Apologize for the previous mistake, I realized struct field was indeed better to be put into the Animal struct because all animals share the attribute name. However, I want different implementation of the same method across different struct that embeds the Animal struct.


Solution

  • Design your Go program to use composition rather than inheritance.

    In your example, why don't you want Animal to have a name? This will print: "Brian is eating":

    package main
    
    import "fmt"
    
    type Animal struct {
        Name    string
    }
    
    func (a *Animal) Eat() {
        fmt.Println(a.Name + " is eating")
    }
    
    type Dog struct {
        Animal
    }
    
    func main() {
        dog := &Dog{Animal{"Brian"}}
        dog.Eat()
    }
    

    You might find this related blog post on composition in Go useful.