定义接口
type Namer interface {
Method1(param_list) return_type
Method2(param_list) return_type
...
}
基础知识
接口不能包含变量,只能定义一组抽象的方法集合。
类型不需要显式声明它实现了某个接口:接口被隐式地实现。只要类型实现了接口包含的所有抽象方法。那么该类型便属于该接口的实现类。
多个类型可以实现同一个接口,一个类型可以实现多个接口。
接口可以嵌套接口。
**声明一个 interface{} 空接口,可接收任何类型。例如:万能切片 []interface{},任意Map map[string]interface{} **。
多态
//利用接口实现多态
type IAnimal interface {
Eat()
}
type Dog struct {
name string
}
func (this *Dog) Eat() {
fmt.Printf("%v 吃 %v\n", this.name, "狗粮")
}
type Cat struct {
name string
}
func (this *Cat) Eat() {
fmt.Printf("%v 吃 %v\n", this.name, "猫粮")
}
func TestIAnimal(t *testing.T) {
//定义一个IAnimal接口类型的切片
anims := []IAnimal{&Dog{"旺财"}, &Cat{"咖啡猫"}}
for n, _ := range anims {
anims[n].Eat()
}
//旺财 吃 狗粮
//咖啡猫 吃 猫粮
}
接口嵌套接口
type IA interface {
AFun()
}
type IB interface {
BFun()
}
//接口可以嵌套接口
type IAB interface {
IA
IB
ABFun()
}
type AB struct {
name string
}
func (this *AB) AFun() {
fmt.Println(this.name + " is A Fun")
}
func (this *AB) BFun() {
fmt.Println(this.name + " is B Fun")
}
func (this *AB) ABFun() {
fmt.Println(this.name + " is AB Fun")
}
type BA struct {
name string
}
func (this *BA) AFun() {
fmt.Println(this.name + " is A Fun")
}
func (this *BA) BFun() {
fmt.Println(this.name + " is B Fun")
}
func (this *BA) ABFun() {
fmt.Println(this.name + " is AB Fun")
}
func TestIAB(t *testing.T) {
//AB和BA结构体都实现了IA、IB、IAB接口
abs1 := []IA{&AB{"AB"}, &BA{"BA"}}
for n, _ := range abs1 {
abs1[n].AFun()
}
//AB is A Fun
//BA is A Fun
abs2 := []IB{&AB{"AB"}, &BA{"BA"}}
for n, _ := range abs2 {
abs2[n].BFun()
}
//AB is B Fun
//BA is B Fun
abs3 := []IAB{&AB{"AB"}, &BA{"BA"}}
for n, _ := range abs3 {
//既可以使用嵌套接口声明的函数,也可以使用本接口声明的函数。
abs3[n].AFun()
abs3[n].ABFun()
}
//AB is A Fun
//AB is AB Fun
//BA is A Fun
//BA is AB Fun
}
类型断言
类型断言即Comma-ok断言。写法为 value, ok := em.(T)。
em:要判断的变量,em必须是interface类型;
T:被判断的类型;
value:返回的值;
ok:是否为该类型;
func TestCD(t *testing.T) {
cd := &CD{}
//如果变量cd没有转换成interface{}类型,报如下错误:
//invalid type assertion: cd.(IA) (non-interface type *CD on left)
if _, ok := interface{}(cd).(IA); !ok {
fmt.Println("没有实现")
}
a := &AB{"AB"}
if v, ok := interface{}(a).(IA); ok {
v.AFun()
}
}