现在面向对象编程都推崇面向接口编程,会提供更好的扩展性等。Go 语言的接口与 Java 中的接口有些类似。
定义
接口代表一种调用契约,一种能力的体现,是多个方法声明的集合。注意只有方法的声明而没有实现。
准备交互的双方,共同遵守事先约定的规则(声明的方法),使得在无须知道对方身份的情况下进行协作。接口关心的是做什么,而不是怎么做、谁来做。
Go 接口实现机制很简洁,只要目标类型方法集内包含接口声明的全部方法,就被视作实现了该接口,无须做显示声明。当然,目标类型可以实现多个接口。
package main
import "fmt"
type teacher interface {
teach()
string() string
}
type EnglishTeacher struct {
name string
age int
}
func(teacher EnglishTeacher) teach() {
fmt.Println("教学生英语")
}
func(teacher EnglishTeacher) string() string {
return fmt.Sprintf("teacher: name %s, age %d", teacher.name, teacher.age)
}
func main() {
var t teacher = EnglishTeacher{"liuaneng", 30}
t.teach() // 教学生英语
fmt.Println(t.string()) // teacher: name liuaneng, age 30
}
如上代码定义了一个 teacher 接口。接口内定义了 teach、string 两个方法。 之后又定义了一个 EnglishTeacher 的结构体类型,并且为结构体定义了两个方法 teach、string。EnglishTeacher 实现了接口 teacher 中的所有方法,所以可以将 EnglishTeacher 对象赋值给 teacher 类型的变量。否则 var t teacher = EnglishTeacher{"liuaneng", 30} 会报错。
接口可以嵌入其他接口类型,相当于将其声明的方法集导入。这就要求不能有同名方法,因为不支持重载。还有,不能嵌入自身或者循环嵌入,否则会导致递归错误。
超集接口变量可以隐式转换为子集,反过来不行。
package main
import "fmt"
type animal interface {
speak() string
}
type bird interface {
animal
fly()
}
type Magpie struct {
}
func(magpie Magpie) speak() string {
return "叽叽喳喳"
}
func(magpie Magpie) fly() {
fmt.Println("飞~~~~")
}
func eat(a animal) {
fmt.Println("干饭去吧")
}
func main() {
var magpie Magpie
var b bird = magpie
eat(b) // 干饭去吧
}