如果❤️我的文章有帮助,欢迎点赞、关注。这是对我继续技术创作最大的鼓励。更多往期文章在我的个人博客
同一类型实现多接口
一个类型能够实现多个接口。并且接口间相互独立,不需要理会对方的实现。
举个例子:学生既可以讲话,也可以走动。我们可以定义出 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 类型的值。