I have an interface which defines a method. I have a struct which implements this interface. In it, I have implemented the methods from this interface and also have additional methods defined.
For example:
package main
import (
"fmt"
)
type Animal interface {
MakeNoise()
}
type Dog struct {
color string
}
/* Interface implementation */
func (d *Dog) MakeNoise() {
fmt.Println("Bark!")
}
/* End Interface implementation */
func (d *Dog) WagTail() {
fmt.Println(d.color + " dog: Wag wag")
}
func NewDog(color string) Animal {
return &Dog{color}
}
func main() {
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
}
On Playground: https://play.golang.org/p/B1GgoNToNl_l
Here, WagTail() is not part of the Animal interface but belongs to the Dog struct. Running this code gives an error
dog.WagTail undefined (type Animal has no field or method WagTail).
Is there a way I could have a struct adhere to an interface and also define it's own methods?
This may help you.
d := dog.(*Dog)
d.WagTail()
On Playground: https://play.golang.org/p/KlNqpmvFTJi
The error described it all:
dog.WagTail undefined (type Animal has no field or method WagTail)
To implement an interface you should implement all methods defined inside it.
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
Now NewDog returns Animal interface which contains MakeNoise method but not WagTail.
The only way to manage your requirement is either create a variable of struct type Dog and then you can call any method having Dog as receiver.
d := &Dog{"Brown"}
d.WagTail()
Or you can return the pointer to Dog struct from NewDog method just like you did in your code mentioned in the comment as:
func NewDog(color string) *Dog {
return &Dog{color}
}
But if the method is not defined in interface you cannot implement it using the struct as method receiver.
Golang provides a way in which:
You can ask the compiler to check that the type T implements the interface I by attempting an assignment using the zero value for T or pointer to T, as appropriate
type T struct{}
var _ I = T{} // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.
If T (or *T, accordingly) doesn't implement I, the mistake will be caught at compile time.
If you wish the users of an interface to explicitly declare that they implement it, you can add a method with a descriptive name to the interface's method set. For example:
type Fooer interface {
Foo()
ImplementsFooer()
}
A type must then implement the ImplementsFooer method to be a Fooer, clearly documenting the fact and announcing it in godoc's output.
type Bar struct{}
func (b Bar) ImplementsFooer() {}
func (b Bar) Foo() {}
Most code doesn't make use of such constraints, since they limit the utility of the interface idea. Sometimes, though, they're necessary to resolve ambiguities among similar interfaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With