其实说白了,接口就是一种协议,统一一个标准。你要调用我,那你就必须实现我的这些方法。我不需要知道你是怎么实现的,但是你一定要实现。甚至在Objec-C当中都不叫interface,直接protocol。
我相信不少刚接触interface的人会跟我有一样的疑惑,我实现接口跟不实现接口没什么区别啊?反正都要实现这些方法。问题的误区就在于,接口的使用并不是单人开发模式的。你写接口你写实现,就不用写接口了。我写接口你实现,接口不就用上了。我不给你规定好了,你怎么知道该实现哪些内容呢。实际上也就是个“规范”。
我实现了某个服务,你可以来调用我的服务,但是调用我的服务之前你必须满足某些约束(实现方法),才能调用我写好了这些服务。这个时候接口的作用就出来了,接口约束了你必须满足的前置条件。看完下面的代码,你就明白了:
package main
import (
"fmt"
)
type Sorter interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}
func Sort(x Sorter) {
for i := 0; i < x.Len()-1; i++ {
for j := i + 1; j < x.Len(); j++ {
if x.Less(i, j) {
x.Swap(i, j)
}
}
}
}
type Xi []int
type Xs []string
func (p Xi) Len() int { return len(p) }
func (p Xi) Less(i int, j int) bool { return p[j] < p[i] }
func (p Xi) Swap(i int, j int) { p[i], p[j] = p[j], p[i] }
func (p Xs) Len() int { return len(p) }
func (p Xs) Less(i int, j int) bool { return p[j] < p[i] }
func (p Xs) Swap(i int, j int) { p[i], p[j] = p[j], p[i] }
func main() {
ints := Xi{44, 67, 3, 17, 89, 10, 73, 9, 14, 8}
strings := Xs{"nut", "ape", "elephant", "zoo", "go"}
Sort(ints)
fmt.Printf("%v\n", ints)
Sort(strings)
fmt.Printf("%v\n", strings)
}
我已经实现好了排序方法,但是我不知道你会传入什么进行排序。于是我写了个接口,你只要实现了接口的全部方法,那么我就允许你调用我的服务,进行排序。
在其他编程语言当中,都是谁提供服务,谁提供接口。你需要调用我的服务,就必须声明你实现了我的接口。
翻译成人话就是我通过一些特定逻辑完成了某个功能,别的模块想要调用我这个功能,就必须把我这个功能里使用的这些函数都给实现了。
而这在逻辑上实际是说不通的,服务提供者怎么会确切的知道服务使用者的具体需求呢?当需求发生变化的时候,服务提供者就需要考虑使用者的需求,从而设计接口。而从理论上来说,每一个服务的开发人员都应该专注于自己的服务。
而go语言不同。go语言的接口是非侵入式接口,只要调用者本身实现了该接口的全部方法,就默认实现了该接口(事实上也确实是实现了这个接口),而不需要显示的声明实现某个接口。这极大的方便了接口的调用,开发人员不必再需要苦想接口的粒度,只需要专注功能函数的实现就可以了。
声明:sunansheng 发表于 2019-04-25 21:54:00 ,共计680字。
转载请署名:Go语言接口为什么是颠覆性的? | www.sunansheng.com