本章学习接口
214_尚硅谷_Go接口特点和语法说明_哔哩哔哩_bilibili
1.interface接口
类似于java的接口,一个接口里有几个未实现方法。
结构体只需实现接口所有同名方法就算实现了接口,无需关键字。
package main
import "fmt"
type Usb interface {
//声明了两个没有实现的方法(像java)
Start()
Stop()
}
type Phone struct {
}
// 让phone实现usb接口方法
func (p Phone) Start() {
fmt.Println("手机,原神,启动!")
}
func (p Phone) Stop() {
fmt.Println("手机,雪豹,闭嘴!")
}
type Camera struct {
}
// 让camera实现usb接口方法
func (c Camera) Start() {
fmt.Println("相机启动!")
}
func (c Camera) Stop() {
fmt.Println("相机闭嘴!")
}
type Computer struct {
}
//编写一个方法Working,接收一个Usb接口变量
//只要是实现了Usb接口(所谓实现了Usb接口,就是实现了usb接口的所有方法)
func (c Computer) Working(usb Usb) {
//通过usb调用Start和Stop方法
usb.Start()
usb.Stop()
}
func main() {
computer := Computer{}
phone := Phone{}
//camera := Camera{}
//关键
computer.Working(phone) //传的是谁调用谁的Start和Stop,因为Phone实现了Usb接口,有这两个方法
//computer.Working(camera)
}
实现接口的类可以当作参数传给接口类型的形参,但是底层调用函数的时候是根据实际对象类型来调用的,所以代码里调用了Phone类型的Start和Stop方法。达成多态(传进符合某个特征的多种事物,会自动调用事物自身的特性)
接口相当于提供一种规范给后面的结构体实现,为了达成高内聚低耦合。
没有implement关键字有个好处,一个结构体实现所有方法后可以同时实现多个接口
2.接口细节
1)就是说定义接口变量可以,但是因为没有实现,所以实际不能由一个接口变量执行这些方法。但是可以把实现了接口的结构体(子类)赋值给接口变量(类似父类)。然后执行,但执行的是实际类型的方法。(有点像java的执行看实际类型执行对应放啊,编译看表面类型有没有)
2)一个自定义类型只有实现了某个接口,才能将该自定义类型的实例变量赋给接类型
3)只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型
4)一个自定义类型可以实现多个接口
这也是上面说的go里不用实现关键字的好处
5)一个接口也可以继承其他接口
如果要实现A接口,那么也要把里面继承的所有接口实现。
package main
type BInterface interface {
test1()
}
type CInterface interface {
test2()
}
// 一个接口继承了其他两个接口,类似于前面继承的格式
// 如果要实现A接口,那么也要把里面BC接口实现。
type AInterface interface {
BInterface
CInterface
test3()
}
type Stu struct {
}
// 实现
func (stu Stu) test1() {
}
func (stu Stu) test2() {
}
func (stu Stu) test3() {
}
func main() {
var stu Stu
var a AInterface = stu
a.test1()
}
9) interface类型默认是一个指针(引用类型),如果没有对interface初始化就使用,那么会输出nil
10)空接口interface没有任何方法,所以所有类型都实现了空接口。什么类型都可以赋给空接口变量
11)多继承接口的时候,继承的接口不能有重复方法,否则报错
12)用指针实现接口,赋值就传结构体指针类型,否则报错