如果❤️我的文章有帮助,欢迎点赞、关注。这是对我继续技术创作最大的鼓励。更多往期文章在我的个人博客
同一类型实现多接口
一个类型能够实现多个接口。并且接口间相互独立,不需要理会对方的实现。 
举个例子:学生既可以讲话,也可以走动。我们可以定义出 Sayer、 Mover接口,如下:
// Sayer 接口
type Sayer interface {
    say()
}
// Mover 接口
type Mover interface {
    move()
}
Student 可以同时实现 Sayer、 Mover接口。
type Student struct {
    name string
}
// 实现Sayer接口
func (s Student) say() {
    fmt.Printf("%s会说早上好\n", s.name)
}
// 实现Mover接口
func (s Student) move() {
    fmt.Printf("%s会靠近\n", s.name)
}
func main() {
    var sayer Sayer
    var mover Mover
    var student = Student{name: "张三"}
    sayer = student
    mover = student
    sayer.say()     // 张三会说早上好
    mover.move()    // 张三会靠近
}
多类型实现同一接口
Golang 中不同类型可以实现同一接口, 该部分上一节已经演示过不过多累述。
这里需要注意的是接口的方法,并没有强制要求由一个类型完全实现,还可以在实现接口的类型中嵌入其他类型、结构体来实现。
举个例子:
// WashingMachine 洗衣机
type WashingMachine interface {
    wash()
    dry()
}
// 甩干器
type dryer struct{}
func (d dryer) dry() {
    fmt.Println("甩一甩")
}
// 海尔洗衣机
type haier struct {
    dryer // 嵌入甩干器
}
func (h haier) wash() {
    fmt.Println("洗一洗")
}
值接收和指针接收实现接口的区别
使用值接收、指针接收 分别实现接口有什么区别呢? 接下来我们通过例子查看一下。
我们分别定义一个 Mover接口、一个 Student结构体。
type Mover interface {
    move()
}
type Student struct {}
值接收者实现接口
func (student Student) move() {
    fmt.Println("学生会走动")
}
此时使用 Student类型 实现接口:
func main() {
	var m Mover
	var zhangsan = Student{}     // 张三是Student类型
	m = zhangsan                 // m可以接收Student类型
	m.move()
	var lisi = &Student{}      // 李四是*Student类型
	m = lisi                   // m可以接收*Student类型
	m.move()
}
上面的代码中我们可以看出:使用值接收实现接口后,不管是结构体还是结构体指针 都可以赋值给接口变量 m。因为 Golang 中有针对指针类型变量求值的语法糖,指针&Student{} 在 lisi 内部会自动求值 *lisi。
指针接收者实现接口
同样的代码,再测试一下使用指针接收的区别:
func (student *Student) move() {
    fmt.Println("学生会走动")
}
func main() {
    var m Mover
    var zhangsan = Student{}     // 张三是Student类型
    m = zhangsan                 // m不可以接收Student类型
    var lisi = &Student{}      // 李四是*Student类型
    m = lisi                   // m可以接收*Student类型
    m.move()
}
此时实现Mover接口的是 *Student 类型,所以不能给m传入Student类型的zhangsan,此时m只能存储 *Student 类型的值。
