Search code examples
gointerface

Replacing struct with interface constructor question


I have this sample code:

// scene.go

var (
  animal *Dog
)

func Init() {
  animal = NewDog()
}

// dog.go

typedef Dog struct {
  name string
}

func (d *Dog) Attack() {}

func NewDog() *Dog {
 dog := new(Dog)
 retutn dog
}

And I want to implement Cat with same public interface as Dog, distinguishing Animal interface

// animal.go -- new file
type Animal interface {
  Attack()
}

// scene.go
var (
  animal *Animal // was *Dog
)

// dog.go

typedef Dog struct {
  Animal // added 
  name string
}

func (d *Dog) Attack() {}

func NewDog() *Animal { // changed *Dog to *Animal
 dog := new(Dog)
 return dog
}

But in this case I get error

cannot use dog (variable of type *Dog) as *Animal value in return statement: *Dog does not implement *Animal (type *Animal is pointer to interface, not interface)

What am I doing wrong and how I should do this ?


Solution

  • You're trying to use interfaces and structs to represent animals like dogs and cats, and you want to define a common interface for them. Here are some corrections to your code:

    var (
        animal Animal // Change from *Animal to Animal
    )
    
    type Dog struct {
        name string
    }
    
    func (d *Dog) Attack() {
        // Implement attack behavior for Dog
    }
    
    func NewDog() Animal {
        return &Dog{}
    }
    
    type Cat struct {
        name string
    }
    
    func (c *Cat) Attack() {
        // Implement attack behavior for Cat
    }
    
    func NewCat() Animal {
        return &Cat{}
    }
    

    This way, both Dog and Cat types implement the Animal interface by implementing the Attack method.

    Note:

    • Use composition over inheritance in Go.
    • Define methods on concrete types to satisfy interfaces rather than embedding the interface itself.
    • Return concrete types that implement the interface from factory functions.