定义接口时,列出所有必需的函数。其他不同的数据类型只要实现了此接口中列出的函数,就能成为此接口类型。
以下的 code,虽然 cat
和 dog
属于不同的类型,但是二者都实现了 Animal
接口指定的 Says()
和 HowManyLegs()
函数,所以 cat
和 dog
都是Animal
类型,所以都能作为参数传递给要求 Animal
类型参数的函数 Riddle
:
package main
import "fmt"
// interface type
type Animal interface {
Says() string
HowManyLegs() int
}
// Dog is the type for dogs
type Dog struct {
Name string
Sound string
NumberOfLegs int
}
// Says is required by the Animal interface
func (d *Dog) Says() string {
return d.Sound
}
// HowManyLegs is required by the Animal interface
func (d *Dog) HowManyLegs() int {
return d.NumberOfLegs
}
// Cat is the type for cats
type Cat struct {
Name string
Sound string
NumberOfLegs int
HasTail bool
}
// Says is required by the Animal interface
func (c *Cat) Says() string {
return c.Sound
}
// HowManyLegs is required by the Animal interface
func (c *Cat) HowManyLegs() int {
return c.NumberOfLegs
}
func main() {
// create a variable of type Dog
dog := Dog{
Name: "dog",
Sound: "woof",
NumberOfLegs: 4,
}
// Pass dog to riddle. Although dog is of type Dog, it satisifies the
// interface requirements for Animal because it implements all of Animal's required functions.
Riddle(&dog)
// Create variable of type Cat
var cat Cat
cat.Name = "cat"
cat.NumberOfLegs = 4
cat.Sound = "meow"
cat.HasTail = true
// Pass cat to riddle. Although cat is of type Cat, it satisifies the
// interface requirements for Animal because it implements all of Animal's required functions.
Riddle(&cat)
}
// Riddle takes a parameter of type Animal, but will accept both Dog and Cat, since both of those types
// satisfy the interface requirements for Animal, because they both have the correct functions.
func Riddle(a Animal) {
riddle := fmt.Sprintf(`This animal says "%s" and has %d legs. What animal is it?`, a.Says(), a.HowManyLegs())
fmt.Println(riddle)
}