Golang 学习——interface 接口学习(一)
Golang中接口定义及实现,空接口,接口嵌套学习
在Golang中,接口是一组方法签名。当类型为接口中的所有方法提供定义时,它被称为实现接口。它与OOP(面向对象编程)
非常相似。接口指定了类型应该具有的方法,类型决定了如何实现这些方法。
如果某个对象实现了某个接口的所有方法,则此对象就实现了该接口。
一.接口定义及实现
1.定义接口
关键字interface
用来定义接口,语法如下:
type interface_name interface {
method_name1([args ...arg_type]) [return_type]
method_name2([args ...arg_type]) [return_type]
method_name3([args ...arg_type]) [return_type]
...
method_namen([args ...arg_type]) [return_type]
}
一个接口中可以定义多个方法,根据逻辑需要,自定义参数和返回值。
2.实现接口
一个结构体实现了某个接口的所有方法,则此结构体就实现了该接口。
我们定义一个Phone
接口,包含两个方法call()
和sendMessage()
type Phone interface {
call()
seenMessage()
}
声明结构体,用来实现接口:
type Huawei struct {
name string
price float64
}
type Xiaomi struct {
name string
price float64
}
声明了Huawei
和Xiaomi
两个结构体,各包含name
和price
两个字段。
接下来,实现Phone
接口,我们先让Huawei
结构体实现该接口所有方法:
func (huawei Huawei) call() {
fmt.Printf("%s 有打电话功能.....\n", huawei.name)
}
func (huawei Huawei) seenMessage() {
fmt.Printf("%s 有发短信功能.....\n", huawei.name)
}
初始化Huawei
结构体,测试接口的方法:
mate30 := Huawei{
name: "Mate 30",
price: 6999,
}
mate30.call()
mate30.seenMessage()
输出:
Mate 30 有打电话功能.....
Mate 30 有发短信功能.....
Huawei
结构体实现了Phone
接口的所有方法,那就认为,则Huawei
结构体实现了Phone
接口。
那如何判断是否实现了该接口,可参考:
Golang学习——如何判断Golang接口是否实现?
我们具体也操作下,看看Xiaomi
结构体若没有实现Phone
接口会发生什么?
实现Phone
接口一个方法:
func (xiaomi Xiaomi) seenMessage() {
fmt.Printf("%s 只有发短信功能.....\n", xiaomi.name)
}
Xiaomi
只实现了 Phone
的 发短信方法,所以认为 Xiaomi
类型未实现了 Phone
接口。我们具体验证下:
首先初始化Xiaomi
结构体,并测试方法
xiaomi9 := Xiaomi{
name: "Xiao 9",
price: 4999,
}
xiaomi9.seenMessage()
输出:
Xiao 9 只有发短信功能.....
seenMessage()
方法测试没问题,我们使用new()
函数来测试下Xiaomi
结构体是否实现了Phone
接口:
var _ Phone = new(Xiaomi)
下图是我从自己的IDE(Goland)截的图,为了方便记录,我将上下文的代码专门换行隔开了。
从图中可以看到,new
下方有红线,鼠标浮上去会显示错误信息,大意就是:Xiaomi
未实现Phone
接口的某些方法,如:call()
,因此不能将Xiaomi
用作电话类型。
二.空接口
空接口 interface{}
:
不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型的数值。
fmt
包下的Print
系列函数,其参数大多是空接口类型,也可以说支持任意类型:
func Print(a ...interface{}) (n int, err error)
func Println(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
1.实例
我们定义一个空接口练习下:
// 定义一个空接口
type Empyt_interface interface {
}
// 定义一个入参为任意类型的函数
func getInfo(arg Empyt_interface) {
fmt.Println("getInfo 函数.....", arg)
}
// 也可以写成如下形式,更推荐
func getInfo2(arg interface{}) {
fmt.Println("getInfo2 函数.....", arg)
}
Golang
很多库的源代码都会以空接口作为参数,表示接受任意类型的参数
我们自己也实战一下:
定义一个值为任意类型的 map
map1 := make(map[string] interface{})
map1["数字"] = 1
map1["字符串"] = "字符串"
map1["布尔"] = false
fmt.Println("map1 ...........", map1)
输出:
map1 ........... map[字符串:字符串 布尔:false 数字:1]
三.接口嵌套
顾名思义,接口嵌套就是一个接口中包含了其他接口,如果要实现外部接口,那么就要把内部嵌套的接口对应的所有方法全实现了。
1.实例
我们定义3个接口,其中有一个接口嵌套了另外两个:
// 定义3个接口
type A interface {
test1()
}
type B interface {
test2()
}
// 定义嵌套接口
type C interface {
A
B
test3()
}
接着我们在定义一个结构体,并实现所有方法:
type Person struct {
//如果想实现接口C,那不止要实现接口C的方法,还要实现接口A,B中的方法
}
func (p Person) test1() {
fmt.Println("test1 方法................")
}
func (p Person) test2() {
fmt.Println("test2 方法................")
}
func (p Person) test3() {
fmt.Println("test3 方法................")
}
初始化结构体,并测试方法:
var person Person = Person{}
// 实现 C 接口的所有方法
person.test1()
person.test2()
person.test3()
输出:
test1 方法................
test2 方法................
test3 方法................
以上就是Golang接口的基础学习,总结了接口的定义及实现,空接口和嵌套接口的概念和使用。
本作品采用《CC 协议》,转载必须注明作者和本文链接