一、接口定义
在讲基础数据类型时,我们曾提了一下 interface 数据类型,这个数据类型就是接口类型
Go 语言不是"传统"的面向对象的编程语言:它里面没有类的概念。但是在go语言里有非常灵活的接口概念,通过它可以实现很多面向对象的特性。接口提供了一种方式来说明对象的行为如果谁能搞定这家您是,他就可以用在这。接口定义了一组方法(方法集),但是这些方法不包含(实现)代码:它们没有被实现(它们是抽象的)。接口里不能保护变量。
type Namer interface { Method1(param_list) retrun_type Method2(param_list) retrun_type ...}
接口的名字由接口名[e]r 后缀组成,例如Printer,Reader,Writer...还有一种不常用的方式(当后缀er不合适是),比如Recoverable,此时接口名已able结尾,或者以I开头
二、 空接口
// 新的类型不是元类型的别名,除了拥有相同的数据㽾结构外,它们之间没有任何关系type Enum int// 可以说Enum 继承了int
自定义的那些数据类型都有来源,那么那些本身就存在的数据类型(int,string..)又怎么来的呢
var name string = "jjj"var in interface{}in = namefmt.Println(in)
任何类型都都默认继承了空接口所有任何类型的数据,空接口变量都可以赋值
三、接口的简单使用
package mainimport "fmt"func main(){ var num int = 3 var n interface{} n = num fmt.Println(n)}
结果3
因为int实现来空接口,所以num可以赋值n
package mainimport "fmt"type Phone interface { Call()}type ViveoPhone struct{}func (this *ViveoPhone) Call(){ fmt.Println("I am Vivo, I can call you!")}type IPhone struct{ me string you string}func (iPhone *IPhone) Call(){ fmt.Println("I am iPhone, I can call you!")}func main(){ var phone Phone phone = &ViveoPhone{} phone.Call() phone = &IPhone{} phone.Call()}
结果I am Vivo, I can call you!I am iPhone, I can call you!
因为VivePhone 和IPhone 这两个结构体 实现Phone所以接口方法,所以默认这两个结构体实现来该接口
四、接口的实现
package mainimport( "fmt")type Car interface{ Run()}type Bike struct{ Type string}func (b *Bike) Run(){ fmt.Printf("this is bike of %s\n",b.Type)}type Bus struct{ Body_num int}func (b *Bus) Run(){ fmt.Printf("bus working,There are currently %d people\n",b.Body_num)}func main(){ var car Car car = &Bike{"马自达"} car.Run() car = &Bus{23} car.Run()}
结果:this is bike of 马自达bus working,There are currently 23 people
五、接口嵌套
一个接口可以包含一个或多个其他的接口,这相当于直接将这些内嵌接口的方法列举在外层接口中一样比如接口 File 包含了 ReadWrite 和 Lock 的所有方法,它还额外有一个 Close() 方法。
type ReadWrite interface { Read(b Buffer) bool Write(b Buffer) bool}type Lock interface { Lock() Unlock()}type File interface { ReadWrite Lock Close()}
六、注意
1、结构体实现来接口的所以方法,即表示结构体实现了该接口。(这种实现方法是隐式实现)2、所有的类型都默认实现了空接口,所以所有类型的变量都可以赋值给空接口变量