接口定义
在计算机科学中,接口是计算机系统中多个组件共享的边界,不同的组件能够在边界上交换信息。如下图所示,接口的本质是引入一个新的中间层,调用方可以通过接口与具体实现分离,解除上下游的耦合,上层的模块不再需要依赖下层的具体模块,只需要依赖一个约定好的接口
Go 语言中的接口是一种内置的类型,它定义了一组方法的签名。它不会暴露出它所代表的对象的内部值的结构和这个对象支持的基础操作的集合;它们只会表现出它们自己的方法。也就是说当你有看到一个接口类型的值时,你不知道它是什么,唯一知道的就是可以通过它的方法来做什么。
接口定义格式为
type 接口类型名 interface{
方法名1( 参数列表1 ) 返回值列表1
方法名2( 参数列表2 ) 返回值列表2
…
}
接口的语言特性
接口是Go这门静态类型语言中唯一“动静兼备”的语言特性。
接口的静态特性:
- 接口类型变量具有静态类型,比如:var e error中变量e的静态类型为error。
- 支持在编译阶段的类型检查:当一个接口类型变量被赋值时,编译器会检查右值的类型是否实现了该接口方法集合中的所有方法。
接口的动态特性:
- 接口类型变量兼具动态类型,即在运行时存储在接口类型变量中的值的真实类型。比如:var i interface{} = 13中接口变量i的动态类型为int。
- 接口类型变量在程序运行时可以被赋值为不同的动态类型变量,从而支持运行时
实现接口的条件
一个对象只要全部实现了接口中的方法,那么就实现了这个接口。换句话说,接口就是一个需要实现的方法列表。
// Sayer 接口
type Sayer interface {
say()
}
type dog struct {}
type cat struct {}
// dog实现了Sayer接口
func (d dog) say() {
fmt.Println("汪汪汪")
}
// cat实现了Sayer接口
func (c cat) say() {
fmt.Println("喵喵喵")
}
接口类型
Go 语言中有两种略微不同的接口,一种是带有一组方法的接口,另一种是不带任何方法的 interface{};Go 语言使用 runtime.iface表示第一种接口,使用 runtime.eface 表示第二种不包含任何方法的接口 interface{}
参考资料
- 《Go 语言第一课》
- 《Go 语言设计与实现》
- 《Go语言圣经》