面向接口编程
在设计我们自己的函数时,我们不去管具体调用我们函数的对象是什么,而且考虑它们都能干什么(即定义接口),只要满足我们的要求(即实现了我们的接口),哪么它们就可以正常使用我们的函数。
如下所示,我们定义了一个KongFuer接口,然后我们还提供了TeachTaekwondo,TeachThaiBoxing这两个函数
package main
import "fmt"
// 想学功夫的对象
type KongFuer interface {
// 必须具备的条件
Leg() // 腿
Arm() // 胳膊
Fist() // 拳头
}
// 我们的函数
// 教跆拳道
func TeachTaekwondo(k KongFuer) {
// 练习5遍腿法
for i := 0; i < 5; i++ {
k.Leg()
}
// 练习1遍拳头
k.Fist()
fmt.Println("跆拳道修炼完毕")
}
// 教泰拳
func TeachThaiBoxing(k KongFuer) {
// 练习3遍腿法
for i := 0; i < 3; i++ {
k.Leg()
}
// 练习3遍胳膊
for i := 0; i < 3; i++ {
k.Arm()
}
// 练习1遍拳头
k.Fist()
fmt.Println("泰拳修炼完毕")
}
现在小明同学想要来找我们学功夫(即调用我们提供的函数),他只需要实现我们所要求的三个函数Leg(),
Arm(),Fist(),然后就可以成功学会我们能提供给他的功夫(即正常调用我们提供的函数)
package main
import "fmt"
// 小明同学
type xiaoMing struct {
Age int
Sex string
}
// 实现KongFuer接口所要求的三个方法
func (x xiaoMing) Leg() {
fmt.Println("小明1.8m的大长腿,开始练习")
}
func (x xiaoMing) Arm() {
fmt.Println("小明的麒麟臂,开始练习")
}
func (x xiaoMing) Fist() {
fmt.Println("小明沙包大的拳头,开始练习")
}
func main() {
// 小明同学登场
xiaoming := xiaoMing{
Age: 18,
Sex: "男",
}
fmt.Println("小明学习跆拳道")
TeachTaekwondo(xiaoming)
fmt.Println("-------------------")
fmt.Println("小明学习泰拳")
TeachThaiBoxing(xiaoming)
}
即使以后拜师的越来越多,甚至猴子也来找我们学习功夫,只要它们有腿,胳膊,拳头(即实现Leg(),
Arm(),Fist()这三个函数),都可以成功学到我们的功夫。
在Golang的源码 src/container/heap
中就可以看到这种编程思想