Golang Interface Link to heading
Golang 中的接口就是一组方法的签名。接口是 Golang 整个类型系统的基石,其他语言的接口是不同组件之间的契约的存在,对契约的实现是强制性的,必须显式声明实现了该接口,这类接口称之为“侵入式接口”。而 Golang 的接口是隐式存在,只要实现了该接口的所有函数则代表已经实现了该接口,并不需要显式的接口声明
// go_interface.go
package main
import (
"fmt"
"unsafe"
)
// Golang 中接口可以看作是一组方法的集合
// 当一个类型 T 实现了 I 接口的全部方法 我们可以认为
// T 类型实现了这个接口
// 这里暂时可以认为 T类型是 I 接口的子类(但要清楚 Golang 没有class 继承的概念)
// 定义一个 Person 接口
type Person interface {
walk()
take()
speak()
}
// 定义一个Human 结构体
type Human struct {
Name string
Age int
}
// 定义一个Adult 结构体 引入Human
type Adult struct {
Human
WorkAddrs string
}
// Adult 以下三个方法 实现了 Person Interface 中定义的函数
func (a Adult) walk() {
fmt.Println(a.Name, "Adult walk ")
}
func (a Adult) take() {
fmt.Println(a.Name, "Adult take ")
}
func (a Adult) speak() {
fmt.Println(a.Name, "Adult speak")
}
func (a Adult) work() {
fmt.Println(a.Name, "Adult Work hard")
}
// 定义一个Child 结构体 引入Human
type Child struct {
Human
SchoolAddrs string
}
// Child 以下三个方法 实现了 Person Interface 中定义的函数
//
func (c Child) walk() {
fmt.Println(c.Name, "Child walk ")
}
func (c Child) take() {
fmt.Println(c.Name, "Child take ")
}
func (c Child) speak() {
fmt.Println(c.Name, "Child speak")
}
func (c Child) study() {
fmt.Println(c.Name "Child study")
}
// 接受类型为 Person interface的参数
func personDo(p Person) {
p.walk()
p.take()
p.speak()
// 类型断言
// 根据类型执行对应类型的不同方法
if c, ok := p.(Child); ok {
c.study()
} else if c, ok := p.(Adult); ok {
c.work()
}
}
func main() {
a := Adult{
Human: Human{
Name: "李建军",
Age: 45,
},
WorkAddrs: "西二旗",
}
fmt.Println(unsafe.Pointer(&a.Human.Age))
fmt.Println(unsafe.Pointer(&a.Age))
personDo(a)
c := Child{
Human: Human{
Name: "李子涵",
Age: 9,
},
SchoolAddrs: "人大附小",
}
personDo(c)
}
$ go run go_interface.go
0xc0000a0190
0xc0000a0190
李建军 Adult walk
李建军 Adult take
李建军 Adult speak
李建军 Adult Work hard
李子涵 Child walk
李子涵 Child take
李子涵 Child speak
李子涵 Child study